顺序表&&单链表

来源:互联网 发布:汽车电气设计软件 编辑:程序博客网 时间:2024/06/09 18:02

顺序表

顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。
顺序表空间是连续的,便于随机访问,在不增容的情况下,尾插的效率高,头插和中间插入不容易实现,增容的代价较高,但其cpu利用率相比链表较高。

单链表

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
一次只开辟一个结点的空间,用来存储当前要保存的数据及指向下一个结点或NULL的指针,所以单链表的空间大小时动态变化的。
链表中的每个节点通过链或指针连接在一起,程序通过指针访问链表中的节点。不支持随机访问。

接下来,我们来了解一些单链表的基本操作!

一,静态顺序表

#include<iostream>#include<stdio.h>#include<stdlib.h>#include<assert.h>using namespace std;const int Max = 10;struct SeqListNode{    int data[Max];    size_t _size;};typedef SeqListNode List;void init(List* head)//初始化顺序表{    head->_size = 0;    memset(head->data,0,Max*sizeof(int));}void print(List* head){    assert(head);    for(size_t i = 0;i<head->_size;i++)    {        cout<<head->data[i]<<" ";    }    cout<<"\n";}int size(List* head){    return head->_size;}void pushBack(List* head, int data){    if(head->_size == Max)        return;    head->data[head->_size]=data;    head->_size++;}void popBack(List* head){    if(head->_size>0)    {        head->_size--;    }}void pushFront(List* head,int data){    if(head->_size == Max)        return;    else    {        for(int i=head->_size;i>0;i--)        {            head->data[i]=head->data[i-1];        }        head->data[0] =data;        head->_size++;    }}void popFront(List* head){    assert(&head);    if(head->_size = 1)    {        head->_size--;    }    else    {        for(size_t i = 1;i<head->_size;i++)        {            head->data[i+1]=head->data[i];        }        head->_size--;    }}bool Empty(List* head){    return head->_size == 0;}void insert(List* head, int pos, int data){    if(pos<0||pos>=Max)        return;    else    {        for(int i = head->_size;i>=pos;i--)        {            head->data[i+1]=head->data[i];        }        head->data[pos]=data;        head->_size++;;    }}void erase(List* head, int pos){    assert(head);    if(pos<0 || pos>=Max)        return;    else    {        for(size_t i = pos;i<head->_size;i++)        {            head->data[i]=head->data[i+1];        }        head->_size--;    }}int Find(List* head,int data){    assert(head);    for(size_t i=0;i<head->_size;i++)    {        if(head->data[i]==data)        {            return i;        }    }}void remove(List* head,int data){    assert(head);    for(size_t i = 0;i<head->_size;i++)    {        if(head->data[i] == data)        {            for(size_t j = i;j<head->_size;j++)            {                head->data[j] = head->data[j+1];            }            head->_size--;        }    }}

二,单链表

1.单链表的数据结构

#pragma once//防止头文件被重复引用typedef int DataType;typedef struct Node//定义结构体{    DataType data;//定义数据    struct Node* next;//指向下一个节点的指针}Node;

2.建立节点

Node* BuyNode(DataType x){    Node* node=(Node*)malloc(sizeof(Node));//用malloc函数动态开启一块空间    node->data=x;    node->next=NULL;    return node;}

3.打印单链表

void PrintList(Node* pHead){    Node* cur=pHead;    while(cur)    {        printf("%d ",cur->data);        cur=cur->next;    }    printf("%\n ");}

4.在单链表的尾部插入节点
这里写图片描述

void PushBack(Node** ppHead, DataType x){    if(*ppHead==NULL)//如果链表为空,直接放入新节点    {        *ppHead=BuyNode(x);    }    else    {        Node* tail=*ppHead;        while(tail->next!=NULL)        {            tail=tail->next;        }        tail->next=BuyNode(x);    }}测试代码:void Test(){    Node*pos;    Node*list=NULL;    PushBack(&list,1);    PushBack(&list,2);    PushBack(&list,3);    PushBack(&list,4);    PrintList(list);    }

5.删除一个单链表的尾部节点
这里写图片描述

void PopBack(Node** ppHead){    if(*ppHead==NULL)//空链表    {        return;    }    else if((*ppHead)->next==NULL)//只有一个节点    {        free(*ppHead);        *ppHead=NULL;    }    else    {        Node* cur=* ppHead;        Node* prev = NULL;        while(cur->next)        {            prev=cur;            cur=cur->next;        }        prev->next=NULL;        free(cur);    }}测试代码void Test(){    Node*pos;    Node*list=NULL;    PushBack(&list,1);    PushBack(&list,2);    PushBack(&list,3);    PushBack(&list,4);    PrintList(list);    PopBack(&list);    PrintList(list);}

6.在单链表指定位置pos前插入一个节点
这里写图片描述

void Insert(Node** ppHead,Node* pos, DataType x){    assert(pos);    if(pos==NULL)    {        PushFront(ppHead,x);    }    else    {        Node* tmp=BuyNode(x);        Node* prev=*ppHead;        while(prev->next!=pos)        {            prev=prev->next;        }        prev->next=tmp;        tmp->next=pos;    }}测试代码:void Test(){    Node*pos;    Node*list=NULL;    PushBack(&list,1);    PushBack(&list,2);    PushBack(&list,3);    PrintList(list);    pos=list;        pos=pos->next;    Insert(&list,pos,30);    PrintList(list);}

7.删除一个无头单链表的非尾节点
无头单链表不知道头节点的地址,所以找不到要删除节点的位置,换个思路可以将问题转化为:
1>记下要删除节点pos的下一个节点next;
2>将next节点的数据赋给pos节点
3>让pos的下一个节点指向next的下一个节点;
4>最后free掉next即可。
这里写图片描述

void EarseNoTail(Node* pos){    Node* next;    assert(pos&&pos->next);    next=pos->next;    pos->data=next->data;    pos->next=next->next;    free(next);}
原创粉丝点击