链表的各种操作的实现和改进
来源:互联网 发布:2017京东双十一知乎 编辑:程序博客网 时间:2024/05/01 12:43
**链表这东西,搞了老子很久的时间,不过貌似有点懂了,分享一下我的代码
代码用c实现( ⊙ o ⊙ )
…………恩,我是分割线(^__^)………………
一.不带头指针的链表的各种操作
1.用双向链表搞定的o( ̄▽ ̄)d**
#include<stdio.h> #include<stdlib.h>typedef struct _node{ int value; struct _node *next; struct _node *back;//这里多定义了一个指针,用来指向前驱结点}Node;typedef struct _list{ Node *tail; //这个用来表示链表的尾部 Node *head; //头部}List;//这里定义了2个结构体,其中的一个的作用是用来修改指针的值的//指针的指针可以用来修改函数体的指针,或者用另一个指针void add(List *pList,int number);void delet(List *pList,int number);void print(List list);int main(int argc,char const *argv[]){ List list; int number; list.head=list.tail=NULL; do{ scanf("%d",&number); if(number!=-1) add(&list,number); }while(number!=-1);/*这里用do比较好,while的话,一开始的number要初始化,比如为0*/ print(list); scanf("%d",&number); delet(&list,number); print(list); return 0;}void add(List *pList,int number){ Node *p=(Node*)malloc(sizeof(Node)); p->value=number; p->next=NULL; p->back=NULL; if(pList->tail){ //用双向链表可以记住链表的尾部,复杂度降低 pList->tail->next=p; p->back=pList->tail; pList->tail=p; } else{ pList->tail=p; pList->head=p; p->back=NULL; }}void delet(List *pList,int number){ Node *p,*q; //这里我写了2种方案,第二种代码少一点 /*for(p=pList->head;p;p=p->next){ if(p->value==number){ if(p!=pList->head&&p!=pList->tail){ p->back->next=p->next; p->next->back=p->back; } if(p==pList->head){ pList->head=p->next; p->next->back=NULL; } if(p==pList->tail){ pList->tail==p->back; p->back->next=NULL; } free(p); break; } }*/ for(q=NULL,p=pList->head;p;q=p,p=p->next){ if(p->value==number){ if(q){ q->next=p->next; p->next->back=q; } else{ pList->head=p->next; p->next->back=NULL; } free(p); break; } }}void print(List list){ Node *p;for(p=list.head;p;p=p->next){ printf("%d\t",p->value);}printf("\n");}
**…………请叫我分割线O(∩_∩)O哈哈~………………
2.补充一种写法:这种写法和头指针差别感觉不是很大**
#include <stdio.h>#include <stdlib.h>typedef struct _node{ int value; struct _node *next;} Node,*linklist;void add(linklist l,int number);void print(linklist l);void find(linklist l,int number);void delete_one(linklist l,int number);void delete_all(linklist l);int main(int argc,char const *argv[]){ Node *head=NULL; linklist l=(linklist)malloc(sizeof(linklist)); l->next=head; /*就这里有一些去吧,和上面的代码基本相同,我就不写注释了*/ int number=1; while(number !=-1) { scanf("%d",&number); if(number!=-1) { add(l,number); } } print(l); scanf("%d",&number); //find(l,number); delete_one(l,number); print(l); //delete_all(l); return 0;}void add(linklist l,int number){ Node *p=(Node*)malloc(sizeof(Node)); p->next=NULL; p->value=number; if(l->next) { Node *last=l->next;//=(Node*)malloc(sizeof(Node)); /* 我觉得这里应该要malloc但是我发现我没malloc也没出现问题,希望看到这篇博客的人去思考一下,评论区帮我解答或者讨论*/ while(last->next) { last=last->next; } last->next=p; //free(last); } else { l->next=p; }}void print(linklist l){ Node *p; for(p=l->next;p;p=p->next) { printf("%d\t",p->value); } printf("\n");}void find(linklist l,int number){ Node *p; int isfound=0; for(p=l->next;p;p=p->next) { if(p->value==number) { printf("we get it!"); isfound=1; break; } } if(!isfound) { printf("we don't get it!"); }}void delete_one(linklist l,int number) { Node *q,*p; for(q=NULL,p=l->next;p;q=p,p=p->next) { if(p->value==number) { if(q) { q->next=p->next; } else { l->next=p->next; } free(p); break; } }}void delete_all(linklist l){ Node *p,*q; for(q=p=l->next;p;) { p=p->next; free(q); } }
**…………分割线…………
二:用头指针的方法来实现链表的各种操作
优点:简化代码,比如add和del各种操作的时候简化代码,至于缺点,笔者目前没发现,下面是代码**
#include<stdio.h>#include<stdlib.h>typedef struct _node{ int value ; struct _node *next;}Node;typedef struct _list{ Node *head;}List;//这里的话,定义了2个结构体void add(List *pList,int number);void print(List *pList);void find (List*pList,int number);void del(List *pList,int number);void clear(List *pList);int main(int argc,int const *argv[]){ List mylist; int number; mylist.head=(Node*)malloc(sizeof(Node));//这里定义了一个头结点 mylist.head->next=NULL; mylist.head->value=0; do{ scanf("%d",&number); if(number!=-1){ add(&mylist,number); } }while(number!=-1); print(&mylist); scanf("%d",&number);// find(&mylist,number); del(&mylist,number); print(&mylist); clear(&mylist);// print(&mylist); return 0;}void add(List *pList,int number){ //add to linked-list Node *p=(Node*)malloc(sizeof(Node)); p->next=NULL; p->value=number; Node *last=pList->head; while(last->next){ //这里定义了头指针,就不需要做一个last是否为空的判断,简化代码 last=last->next; //和上面的没有头指针进行比较就可以得出结论 } last->next=p;}void print(List *pList){ Node* p; for(p=pList->head->next;p;p=p->next){ //一个超经典的循环,做一个遍历咯。。。 printf("%d\t",p->value); } printf("\n");}void find(List *pList,int number){ Node *p; int isfound=0; //一个小技巧,注意一下就ok啦啦 for(p=pList->head;p;p=p->next){ if(p->value==number){ printf("number is find!\n"); isfound=1; break; //这个不漏了,当然了漏了输出的时候也可以看出来 } } if(!isfound) printf("not find!\n");}void del(List *pList,int number){ Node *p,*q; for(q=NULL,p=pList->head;p;q=p,p=p->next){ if(p->value==number){ q->next=p->next; free(p); //free(q); 如果你手贱free了q,你试一下就知道发生了什么 break; } }}void clear(List *pList){ Node *p,*q; for(p=pList->head;p;p=q){ //很常用的手法,画图理解一下 q=p->next; free(p); }}
最后说一句,头指针加上双向链表的,有兴趣的自己去写
typedef struct _list{
Node *head;
}List;
这个里面加一个Node *tail的事情了。
0 0
- 链表的各种操作的实现和改进
- 对链表的基本实现和各种操作
- 各种算法的改进
- 实现链表的各种操作(利用链表来实现)
- 线性表的各种操作实现
- 线性表各种操作的实现
- 使用Lua实现链表的各种操作
- 单循环链表各种操作的C语言实现
- 对链表各种操作的实现(C语言)
- 实现堆的各种操作
- 链表的各种操作
- 链表的各种操作
- 链表的各种操作
- 链表的各种操作
- 链表的各种操作
- 链表的各种操作
- C语言版--图的实现和各种操作
- C语言版--图的实现和各种操作
- day19/SystemInfo.java
- Demo08:ListView
- day19/TransStream1.java
- R中正太检验的方法
- 从屏幕输入一行数字,以空格分隔,如何分别存放到数组中
- 链表的各种操作的实现和改进
- day19/TransStream2.java
- 上传文件到服务器类
- xUtils系列之DbUtils-开启Sqlite3外键约束
- day19/TransStream.java
- 【Java】实现一个递归和非递归的reverse,它们能把一个表翻转过来。
- 【C++】智能指针
- Linux netstat命令详解
- day19/ZhuangShiSheJi.java