链表的各种操作的实现和改进

来源:互联网 发布: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
原创粉丝点击