链表合集
来源:互联网 发布:windows电脑怎么调亮度 编辑:程序博客网 时间:2024/06/03 21:29
单链表
#include<stdio.h>#include<stdlib.h>typedef int datekey;typedef struct link_node{ datekey info; struct link_node *next;}node;node *init(){ return NULL;}void display(node *head)//输出各个节点的值{ node *p; p=head; if(p==NULL) { printf("链表是空的\n"); exit(1); } while(p) { printf("%-5d",p->info); p=p->next; } printf("\n");}node *find(node *head,int i)//返回第i个节点的地址{ int j=1; node *p=head; if(i<1) return NULL; while(p&&i!=j) { p=p->next; j++; } return p;}node *insert(node *head,datekey x,int i)//在第i个节点插入键值为x的节点{ node *p,*q; q=find(head,i); if(!q&&i!=0) { printf("找不到%d节点",i); exit(1); } p=(node *)malloc(sizeof(node)); p->info=x; if(i==0) { p->next=head; head=p; }else { p->next=q->next; q->next=p; } return head;}node *dele(node *head,datekey x) //删除键值为x的节点{ node *pre=NULL; node *p=head; if(!head) { printf("链表是空的\n"); exit(1); } while(p&&p->info!=x) pre=p,p=p->next; if(p) { if(!pre) head=p->next; else pre->next=p->next; free(p); } return head;}int main(){ int i=0,n; while(~scanf("%d",&n)) { node *head; head=init(head); for(i=0;i<n;i++) { int x; scanf("%d",&x); head=insert(head,x,i); } printf("请输入要插入的值和节点\n"); int a,b; scanf("%d%d",&a,&b); head=insert(head,a,b); display(head); printf("输入要删除的值:\n"); scanf("%d",&n); dele(head,n); display(head); }}
带头结点的单链表
#include<stdio.h>#include<stdlib.h>#define maxn 1111typedef int datekey;typedef struct link_node{ datekey info; struct link_node *next;}node;node *init(){ node *head=(node *)malloc(sizeof(node)); head->next=NULL; return head;}node *find(node *head,int i){ int j=0; node *p=head; if(i<0) { printf("不存在这样的节点\n"); exit(1); } while(p&&i!=j) p=p->next,j++; return p;}node *insert(node *head,datekey x,int i){ node *p=find(head,i); if(!p) { printf("不存在这样的节点\n"); exit(1); } node *q=(node*)malloc(sizeof(node)); q->info = x; q->next=p->next; p->next=q; return head;}void display(node* head){ node *p=head; p=p->next; if(!p) { printf("表是空的\n"); exit(1); } while(p) printf("%-5d",p->info),p=p->next; printf("\n");}node *dele(node* head, datekey x){ node *pre=head; node *p=head->next; while(p&&p->info!=x) pre=p,p=p->next; if(p) { pre->next=p->next; free(p); } return head;}int main(){ int n,i; datekey x; while(~scanf("%d",&n)) { node *head; head=init(); for(i=0;i<n;i++) { scanf("%d",&x); head=insert(head,x,i); } display(head); printf("要插入的数和节点\n"); scanf("%d%d",&x,&i); insert(head,x,i); display(head); printf("输入要删除的数\n"); scanf("%d",&x); dele(head,x); display(head); }}
循环链表
#include<stdio.h>#include<stdlib.h>typedef int datetype;typedef struct link_node{ datetype info; struct link_node *next;}node;node * init(){ return NULL;}node *create() //创建一个个循环链表,以输入-1结束{ int x; node *head=(node *)malloc(sizeof(node)),*p,*q; scanf("%d",&x); if(x!=-1) head->info=x; else return NULL; p=head; //p始终指向表的末尾 while(scanf("%d",&x)&&x!=-1) { q=(node *)malloc(sizeof(node)); q->info=x; p->next=q; //p指向插入的节点的地址 p=p->next; //p指向表的末尾 } p->next=head; //循环链表,表的末尾指向头指针 return head;}void display(node *head) //输出表的内容{ node *p=head; if(!head) { printf("循环链表是空的\n"); } else { p=head->next; //先输出头结点的值 printf("%-5d",head->info); while(p!=head) //当再一次指向头结点时,链表遍历完全 { printf("%-5d",p->info); p=p->next; } } printf("\n");}node *find_rear(node *head) //找到表的尾指针{ node *p=head; if(!head) return NULL; while(p->next!=head) p=p->next; //若当前节点的指向的是头指针,循环结束 return p;}node *insert(node *head,int i,datetype x) //链表中在第i节点后插入键值为x的节点{ node *p=head,*q,*rear; rear=find_rear(head); //找到尾指针 int j=1; //计数从1始,指向当前头节点 q=(node *)malloc(sizeof(node)); q->info=x; if(i<0) { printf("这样的节点不存在\n"); return NULL; } if(i==0&&!head) //若链表为空且插入的点在第0位 { head=q,head->next=head;//直接接将将待插入点改为头结点并指向自己 return head; } if(i==0&&head) //若插入节点在头部,但链表不为空 { q->next=head,head=q; //将待插入点指向原来的头结点,改变头结点 rear->next=head; //使尾指针指向新的头结点 return head; } if(i>0&&!head) //节点大于0,且链表为空,不存在 { printf("无法找到这样的节点\n"); return head; } while(p->next!=head&&i!=j) p=p->next,j++; //节点大于1,链表不为空,扫描链表,找到第i个节点 if(i>0&&i==j) //找到节点,进行插入 { q->next=p->next; p->next=q; }else if(i!=j) printf("不存在这样的节点\n"); return head;}node *dele(node *head,datetype x){ node *pre=NULL,*p=head; if(!head) { printf("链表是空白的\n"); return head; } while(p->next!=head&&p->info!=x) pre=p,p=p->next; //pre始终指向p节点的前驱 if(p->info!=x) { printf("不存在这样的点\n"); return head; } if(head->info==x) //要删除头节点时 { if(head->next==head) //链表只有头结点,则返回空 { free(head); return NULL; } else //否则找到到尾指针,使得尾指针指向删除后新的头指针 { pre=head->next; while(pre->next!=head) pre=pre->next; pre->next=head->next; free(head); head=pre->next; } } else pre->next=p->next,free(p);//删除的点在中间某个地方时,将p的前驱指向p的后继 return head;}int main(){ node *head,*rear; while(1) { int id,x; head=create(); display(head); printf("输入要插入的节点和值:"); scanf("%d%d",&id,&x); head=insert(head,id,x); display(head); printf("输入要删除的值:"); scanf("%d",&x); head=dele(head,x); display(head); }}
双向链表
#include<stdio.h>#include<stdlib.h>typedef int datatype;typedef struct dlink_list{ datatype info; struct dlink_list *llink,*rlink;//指向前驱的指针和指向后继的指针}node;node *init(){ return NULL;}void display(node *head)//输出链表各节点的值{ node *p=head; if(!head) //链表为空 { printf("链表是空的\n"); return NULL; } while(p) { printf("%-5d",p->info); p=p->rlink; } printf("\n");}node *create() //创建一个双向链表,以输入-1结束{ int x; node *head,*p,*q; head=(node *)malloc(sizeof(node)); scanf("%d",&x); if(x!=-1) head->info=x,head->rlink=NULL,head->llink=NULL; else {free(head);return NULL;}//若只输入-1,则释放申请的空间,返回空链表 p=head;//p始终指向当前链表的尾部 while(scanf("%d",&x)&&x!=-1) { q=(node *)malloc(sizeof(node)); q->info=x; p->rlink=q; //尾部指向新插入的节点 q->llink=p; //使要插入的节点指向原链表的尾部 p=p->rlink;//p指向新链表的尾部 } p=p->rlink=NULL; //使链表尾部指向NULL return head;}node *insert(node* head, int i, int x) //插入一个新节点,插在第i的节点后面{ int j=1; node *p,*q; q=(node *)malloc(sizeof(node)); q->info=x; if(i<0) { printf("不存在这样的节点\n"); free(q); return head; } if(i==0&&!head) //插在头结点前面并且此时链表为空 { head=q; //直接将待插入点改为头结点 head->rlink=NULL; //前驱后继各指向空 head->llink=NULL; return head; } if(i==0&&head) //插在头结点前面 { q->rlink=head; //新的节点指向原头结点 head->llink=q; //原头结点的左指针指向新插入的节点 head=q; //改变头结点 head->llink=NULL;//使得新的头节点的左指针指向NULL return head; } p=head; while(p&&i!=j) p=p->rlink,j++; //当插入节点在中间某个地方时 if(p) { if(p->rlink==NULL) //插入的节点在尾部 { p->rlink=q;//原链表的尾部的右指针指向新插入节点 q->llink=p;//新插入节点的左指针指向原链表尾部 p=p->rlink;//p指向当前指针待插入节点 p->rlink=NULL; //尾部的指针指向NULL } else { q->rlink=p->rlink; //使得新插入节点的右指针指向待插入节点的后一个节点 p->rlink=q; //使得当前节点指向 q->rlink->llink=q;//当前节点后一个节点的左指针指向待插入节点 q->llink=p; //待插入节点的左指针指向当前节点 } return head; } else { printf("不存在这样的节点\n"); free(q); return head; }}node *dele(node* head, int x){ node *p=head; if(!head) { printf("链表是空的\n"); return NULL; } while(p&&p->info!=x) p=p->rlink; //找到第一个等于x的节点,p指向待删除的节点 if(head->info==x)//头结点等于x的情况 { if(head->rlink==NULL) free(p),head=NULL; //若只有头结点,返回空 else head=head->rlink,head->llink=NULL,free(p); //否则下一个作为头结点,头结点的左指针指向为空,释放空间 return head; } if(p) //当找到等于x的节点 { if(p->rlink==NULL) p->llink->rlink=NULL,free(p); //删除的点在尾部,尾指针向前移 else { p->llink->rlink=p->rlink; // 当前节点的前驱指向当前节点的后继 p->rlink->llink=p->llink; //当前节点后继的左指针指向当前节点的前驱 free(p); } return head; } else { printf("不存在这样的节点\n"); return head; }}int main(){ int x,id; node *head; printf("创建一个链表:\n"); head=create(); display(head); printf("输入要插入的节点和值:"); scanf("%d%d",&id,&x); head=insert(head,id,x); display(head); printf("输入要删除的数据:"); scanf("%d",&x); head=dele(head,x); display(head);}
0 0