数据结构链表基本操作

来源:互联网 发布:二元期权数据 编辑:程序博客网 时间:2024/06/01 08:59

前文:

   前面介绍了线性表的基本操作,今天将会介绍链表的基本操作以及原理。

正文:

     首先链表和线性表不同的是,链表的空间不是连续存放的,它是用指针指向下一个节点地址把每一个节点连接起来的。下面我将写出单链表,循环单链表,双向链表的基本操作:


在这里声明一点下面的所有类型链表操作的头结点,我是直接在主函数中定义的,并且不是使用动态内存创建的,所以初始化中没有在创建头结点,并且销毁函数也不需要销毁头结点。


一:单链表:
typedef struct Node{int data;           //存放的数据struct Node *next;   //指向下一个节点}Node,*List;
1.初始化:
void Init(List ps)   //初始化{assert(ps != NULL);ps->next = NULL;      //指向空说明除了头节点,后面不在有其他的节点}
2.头插法:
bool Insert_head(List ps, int val)       //头插法 (从头结点往后插入新的节点){assert(ps != NULL);                  Node *p = (Node *)malloc(sizeof(Node));   //新建立的节点p->data = val;                     //把数据放入节点中p->next = ps->next;                 //把新建的节点的第一根线连接起来,先连起后线ps->next = p;                        //再连起前线return true;}
3.尾插法:
bool Insert_tail(List ps, int val)     //尾插法  (从尾结点往后插入新的节点){Node *p = (Node *)malloc(sizeof(Node));   //创立新节点p->data = val;                            //放入数据Node *q; for (q = ps; q->next != NULL; q = q->next);   //先找到尾结点p->next = q->next;         //和头插法同理q->next = p;return  true;}
4.在链表中查找放有key的节点
Node * Search(List ps, int key)                  //在链表中查找放有key的节点{for (Node *p = ps->next; p != NULL; p = p->next)    //从头结点下一个节点开始查找,头结点中没有数据{if (p->data == key){return p;                             //找到则返回节点}}return NULL;}
5.删除数据是key的节点
bool Delete(List ps, int key)                //删除数据是key的节点{Node *p;for (p = ps; p->next != NULL; p = p->next)     {if (p->next->data == key){break;}}if (p->next == NULL)           //说明没有找到key数据的节点{return false;}p->next = p->next->next;       //指向该节点的下一个节点地址,就相当于删除了这个节点。return true;}
6.获取节点个数
int Getlength(List ps)  //获取节点个数{int count = 0;for (Node*p = ps; p->next != NULL; p = p->next)     //包括头结点{count++;}return count;}
7.摧毁节点
void Destroy(List ps)   //摧毁节点{Node *p;while (ps->next != NULL){p = ps->next;           //每次只删除第一个节点ps->next = p->next;     //再把第一个节点后面的节点地址放入ps的next中free(p);              //释放掉节点}}
8.清楚节点
void Clear(List ps){Destroy(ps);}
9.打印
void Show(List ps)       //打印{for (Node *p = ps->next; p != NULL; p = p->next)   //不打印头结点内容,因为头结点中没有存放数据{printf("%d,", p->data);}printf("\n");}
10.判断是不是只有一个头结点
bool Isempty(List ps)   //判断是不是只有一个头结点{return ps->next == NULL;}
以上是单链表的基本操作。
二:双向链表:(只写和单链表不同的操作)
因为我们在使用单链表的时候发现,我们可以往后走,但是当我们想要往回走的时候就会显的很麻烦,因此现在我们引入双向链表,就在原来单链表的基础上我们加上指向上一个节点的地址的指针。
typedef struct Node{int data;struct Node *next;    //指向下一个节点的地址struct Node *prio;    //指向上一个节点地址}Node,* List;

1.初始化:
void Init(List ps)   //初始化{assert(ps != NULL);ps->next = NULL;     //后驱指向空ps->prio = NULL;     // 前驱指向空}
2.头插法:
bool Insert_head(List ps, int val)   //头插法{assert(ps != NULL);Node *p = (Node *)malloc(sizeof(Node)); //创立新的节点p->data = val;            //把数据放入节点中p->next = ps->next;       //连接后驱的前线ps->next = p;             //连接后驱的后线p->prio = ps;             //连接前驱的后线if (p->next != NULL)      //在连接前驱的前线时要考虑,该节点后面还有没有节点{p->next->prio = p;    //连接前驱的前线}return true;}


3.尾插法:
bool Insert_tail(List ps, int val)   //尾插法{Node *p = (Node *)malloc(sizeof(Node));p->data = val;Node *q;for (q = ps; q->next != NULL; q = q->next);   //找到尾结点p->next = q->next;                //和头插法同理q->next = p;p->prio = ps;if (p->next != NULL){p->next->prio = p;}return true;}
4.删除数据:
bool Delete(List ps, int key){Node *p = Search(ps, key);   //因为双线链表的每个节点都带有前后两个节点的地址,所以不需要在从头结点查找了,所以可以直接调用Search函数if (p == NULL){return false;     //没找到 返回错误}p->prio->next = p->next;      //找到该节点就把这个节点的前驱的前线连接到该节点的后驱上。这样就直接穿过该节点,想当于删除它if (p->next != NULL){p->next->prio = p->prio;   //再把该节点的后驱的后线连接到该节点的前驱上。}return true;}


以上就是双向链表的基本操作,没写到的请看单链表。

三:循环单链表:
循环单链表它的尾结点的next 不在是指向NULL,而是指向了头结点。以下我写出循环单链表的基本操作(只写和单链表不同的操作)。
typedef struct Node{int data;struct Node *next;}Node,*List;
1.初始化:
void Init(List ps)      //初始化{assert(ps != NULL);ps->next = ps;            //指向的不在是NULL而是头结点。}


2.判断是否只有一个节点:
bool Isempty(List ps)     //判断是否只有一个头结点{return ps->next == ps;    //不再是判断next是否指向NULL而是头结点}

后面的操作都是同理,只需要把单链表中判断最后节点next指向NULL都改成指向头结点ps即可


以上是最近刚学的基础链表的基础操作总结,因为是刚刚所学,所以如果有写错的地方,希望大家指出,其次后面我还会着重写静态链表和链表的中运用方法。希望大家一起努力,好好学习。

在IT编程方面你所学的永无止境,千万不要夜郎自大,后面的内容太多,太难。语言固然重要,但是在这些编程技巧和思想面前又显得不那么重要,主要原因是后面的内容掌握好你就是工程师,掌握不好你只是码农。














原创粉丝点击