当前位置:   article > 正文

单链表的十三个基本操作(全)_单链表的基本操作

单链表的基本操作

目录

一、初始化单链表

二、插入

三、删除

四、查找

4.1 按位查找

4.2 按数查找

五、逆置

六、排序

七、删除指定数

八、交换位置

8.1 按位交换

8.2 按数交换 

九、求单链表长度

十、修改

10.1 按位修改

10.2 按数修改

十一、最大值

十二、按序插入

十三、删除重复值

附:系列文章


一、初始化单链表

初始化一个带头结点的单链表,需要一个数据域和一个指针域

  1. typedef struct node{
  2. int data; //数据域
  3. struct node * next; //指针域
  4. }node,*pnode;
  5. pnode init_node(){
  6. pnode head=(pnode)malloc(sizeof(node));
  7. head->next=NULL;
  8. }

二、插入

单链表的插入操作,不需要担心空间不足的情况,我们需要先找到插入的位置,然后再执行插入操作,注意这里我们要找的是需要插入位置的前面一个结点,这样子方便我们进行插入操作,插入操作的具体步骤为:找到插入位置前一个结点——>判断插入位置是否合法——>新建一个要插入的结点——>将该新结点插入进单链表

  1. int insert_node(pnode head,int i,int e){
  2. pnode p=head; //头结点
  3. int j=0;
  4. while(p&&j<i-1){ //获取插入位置前面一个结点
  5. p=p->next;
  6. j++;
  7. }
  8. if(!p||j>i-1){ //判断是否合法
  9. return 0;
  10. }
  11. pnode pnew=(pnode)malloc(sizeof(node)); //新建一个结点
  12. pnew->data=e;
  13. pnew->next=NULL;
  14. pnew->next=p->next; //插入单链表中
  15. p->next=pnew;
  16. return 1;
  17. }

三、删除

单链表的删除操作,同插入操作一样,我们需要先找到删除的位置,然后执行删除,具体步骤为:找到删除位置的前一个结点——>判断要删除的位置是否合法——>删除该结点

  1. int delete_node(pnode head,int pos,int *val){
  2. pnode p=head; //头结点
  3. int j=0;
  4. while(p&&j<pos-1){ //找到要删除元素的前面一个结点
  5. p=p->next;
  6. j++;
  7. }
  8. if(!p||j>pos){ //判断是否合法
  9. return 0;
  10. }
  11. pnode s;
  12. s=p->next; //s存放要删除的结点
  13. *val=s->data; //val存放要删除结点的数据域,便于输出
  14. p->next=s->next; //删除
  15. free(s); //释放内存
  16. return 1;
  17. }

四、查找

单链表的查找操作,同插入删除操作一样,需要找位置,但是不同的是,这里我们直接找该结点的位置即可,不需要用到它前面的结点

4.1 按位查找

按位查找,只需要通过循环得到要查找结点的位置即可,利用val保存该结点的数据域,便于输出查找的结点值

  1. int find1_node(pnode head,int pos,int *val){
  2. int i=0;
  3. pnode p=head;
  4. while(p&&i<pos){ //找到要查找的结点
  5. p=p->next;
  6. i++;
  7. }
  8. if(!p||i>pos){ //判断是否合法
  9. return 0;
  10. }
  11. *val=p->data; //val保存该节点数据域,便于输出
  12. return 1;
  13. }

4.2 按数查找

按数查找,我们利用循环即可得到要查找结点的位置

  1. int find2_node(pnode head,int *pos,int val){
  2. pnode p=head;
  3. int i=0;
  4. while(p){ //循环,找到val,输出位置
  5. if(val==p->data){
  6. *pos=i+1;
  7. break;
  8. }
  9. p=p->next;
  10. i++;
  11. }
  12. return 0;
  13. }

五、逆置

1、单链表的逆置操作,我们需要三个指针,一个指向头结点后面的第一个有效结点,一个指向第二个有效结点,还有一个指向第三个有效结点

2、逆置的具体步骤为:将第一个有效结点q与后面断开,q变成了该单链表逆置后的尾结点——>将第二个有效结点p连接到头结点后面——>将第三个有效结点r给p继续循环放到头结点后面——>得到逆置后的单链表

  1. int nizhi_node(pnode head){
  2. pnode p,q,r; //p,q,r三个指针
  3. p=head->next;
  4. q=p->next;
  5. p->next=NULL; //断开单链表,将单链表分为两个部分
  6. while(q){ //循环
  7. r=q->next; //有点像头插法
  8. q->next=head->next;
  9. head->next=q;
  10. q=r;
  11. }
  12. }

六、排序

单链表的排序算法,就是利用双重循环,第一重循环是遍历单链表的所有结点,第二重循环用来判断,寻找有没有数据域相同的结点,如果有,删除;如果没有,执行下一重循环

  1. int sort_node(pnode head){
  2. pnode p,q;
  3. int t;
  4. for(p=head->next;p;p=p->next){ //第一重循环,遍历单链表
  5. for(q=p->next;q;q=q->next){ //第二重循环,进行排序
  6. if(p->data>q->data){
  7. t=p->data;
  8. p->data=q->data;
  9. q->data=t;
  10. }
  11. }
  12. }
  13. }

七、删除指定数

1、单链表删除指定大于x小于y的数,我们需要两个指针,一个指向头结点,还有一个指向头结点后面第一个有效结点

2、删除的方法为:循环判断如果存在结点的数据域大于x并且小于y,则将该结点删除(p始终是q前面的那个结点,方便删除)

  1. int delete1_node(pnode head,int x,int y){
  2. pnode p=head;
  3. pnode q=head->next;
  4. while(q){
  5. if(q->data>x&&q->data<y){
  6. p->next=q->next; //找到就删除
  7. pnode s=q;
  8. q=q->next;
  9. free(s);
  10. }else{
  11. p=p->next; //p始终是q前面的那个结点
  12. q=q->next;
  13. }
  14. }
  15. }

八、交换位置

单链表将指定位置的结点与其后面的一个结点交换位置,分为两种情况,一种是按位交换,还有一种是按数交换

8.1 按位交换

按位交换,我们先通过循环找到要交换的位置,然后执行交换

  1. int jiaohuan1_node(pnode head,int pos){
  2. int i=0;
  3. pnode p=head;
  4. while(p&&i<pos-1){ //先找到要交换的位置
  5. p=p->next;
  6. i++;
  7. }
  8. if(!p||i>pos-1){ //判断位置是否合法
  9. return 0;
  10. }
  11. pnode s=p->next; //执行交换
  12. pnode r=s->next;
  13. s->next=r->next;
  14. p->next=r;
  15. r->next=s;
  16. }

8.2 按数交换 

按数交换,我们先通过循环找到该元素的位置,然后执行交换

  1. int jiaohuan2_node(pnode head,int val){
  2. pnode p,q,r;
  3. p=head->next;
  4. while(p){
  5. q=p->next;
  6. if(q->data==val){ //找位置,交换,思想一样
  7. break;
  8. }
  9. p=p->next;
  10. }
  11. r=q->next;
  12. q->next=r->next;
  13. p->next=r;
  14. r->next=q;
  15. }

九、求单链表长度

单链表求长度,使用循环即可得到

  1. int len_node(pnode head){
  2. int len=0;
  3. pnode p=head->next;
  4. while(p){ //循环
  5. len++; //单链表长度加1
  6. p=p->next;
  7. }
  8. return len;
  9. }

十、修改

单链表的修改操作,分为两种情况,一种是按位修改,另一种是按数修改

10.1 按位修改

按位修改,先通过循环找到要修改的结点,然后直接进行修改就好啦

  1. int change1_node(pnode head,int pos,int val){
  2. pnode p=head;
  3. int i=0;
  4. while(p&&i<pos){ //找位置
  5. p=p->next;
  6. i++;
  7. }
  8. if(!p&&i>pos){
  9. return 0;
  10. }
  11. p->data=val; //修改
  12. return 1;
  13. }

10.2 按数修改

按数修改,也是通过循环找到结点,再执行修改操作就好啦

  1. int change2_node(pnode head,int val1,int val2){
  2. pnode p=head->next;
  3. while(p){
  4. if(p->data==val1){ //找相同元素,直接修改
  5. p->data=val2;
  6. }
  7. p=p->next;
  8. }
  9. }

十一、最大值

单链表输出最大值,我们直接通过循环找到最大值就好啦

  1. int max_node(pnode head){
  2. int max;
  3. pnode p=head->next;
  4. max=p->data;
  5. while(p){ //循环判断,找出最大值
  6. if(max<p->data){
  7. max=p->data;
  8. }
  9. p=p->next;
  10. }
  11. return max;
  12. }

十二、按序插入

单链表按序插入结点,运用循环找到要插入的位置的前面一个结点,执行插入操作即可

  1. int insert_sort_node(pnode head,int x){
  2. pnode p=head;
  3. pnode pnew=(pnode)malloc(sizeof(node));
  4. pnew->data=x;
  5. pnew->next=NULL;
  6. while(p->next->data<x&&p->next!=NULL){ //循环找到要插入位置的前一个结点
  7. p=p->next;
  8. }
  9. pnew->next=p->next;
  10. p->next=pnew;
  11. }

十三、删除重复值

单链表删除重复值,我们需要两个指针,一个指向要删除的结点,另一个指向要删除结点的前面一个结点,我们运用循环找到相同的结点,执行删除操作即可

  1. int delete_same_node(pnode head){
  2. pnode p,q; //两个指针
  3. p=head->next;
  4. while(p){
  5. q=p;
  6. while(q->next){
  7. if(p->data==q->next->data){ //遇到相同的就执行删除操作
  8. pnode s=q->next;
  9. q->next=s->next;
  10. free(s);
  11. }else{
  12. q=q->next;
  13. }
  14. }
  15. p=p->next;
  16. }
  17. }

附:系列文章

序号文章目录直达链接
1顺序表的十个基本操作(全)https://want595.blog.csdn.net/article/details/127139051
2单链表的十三个基本操作(全)https://want595.blog.csdn.net/article/details/127139598
3四种创建单链表的方法https://want595.blog.csdn.net/article/details/127017405
4删除重复元素(顺序表、单链表)https://want595.blog.csdn.net/article/details/127023468
5两个有序表的合并(三种方法)https://want595.blog.csdn.net/article/details/127104602
6一元多项式相加问题(两种方法)https://want595.blog.csdn.net/article/details/127131351
7约瑟夫环问题(三种方法)https://want595.blog.csdn.net/article/details/127019472
8顺序栈与链栈https://want595.blog.csdn.net/article/details/127035609
9顺序循环队列与链队列https://want595.blog.csdn.net/article/details/127040115
10后缀表达式的转换(栈的运用)https://want595.blog.csdn.net/article/details/127088466
11简单表达式的计算(两种方法)https://want595.blog.csdn.net/article/details/127121720
12next数组(详细求法)https://want595.blog.csdn.net/article/details/127217629
13BF算法(具体应用)https://want595.blog.csdn.net/article/details/127138894
14串的模式匹配相关问题(BF算法、KMP算法)https://want595.blog.csdn.net/article/details/127182721
15二叉树的遍历(七种方法)https://want595.blog.csdn.net/article/details/127472445

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/636587
推荐阅读
相关标签
  

闽ICP备14008679号