数据结构:链表
单链表
插入结点
p、q间插入
#include <stdio.h> #include <stdlib.h> //单链表定义 struct slist { int data; struct slist *next; }; //简单插入一个数【p、q间插入】 void main() { struct slist *head,*p,*q; //head为头指针,始终指向链表的起始节点 //构建链表 q = (struct slist *)malloc(sizeof(struct slist)); p = (struct slist *)malloc(sizeof(struct slist)); head = p; p ->data = 10; q ->data = 20; p ->next = q; q ->next =NULL; //插入一个节点node = 15 struct slist *node = (struct slist*)malloc(sizeof(struct slist)); node ->data = 15; node ->next = p ->next; p ->next = node; //输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); free(p); free(node); }
表头插入
//简单插入一个数【表头插入】 void main() { struct slist *head,*p,*q; //head为头指针,始终指向链表的起始节点 //构建链表 q = (struct slist *)malloc(sizeof(struct slist)); p = (struct slist *)malloc(sizeof(struct slist)); head = p; p ->data = 10; q ->data = 20; p ->next = q; q ->next =NULL; //表头插入一个节点node = 5 struct slist *node = (struct slist*)malloc(sizeof(struct slist)); node ->data = 5; node ->next = head; head = node; //输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); free(p); free(node); }
表尾插入
//简单插入一个数【表尾插入】 void main() { struct slist *head,*p,*q; //head为头指针,始终指向链表的起始节点 //构建链表 q = (struct slist *)malloc(sizeof(struct slist)); p = (struct slist *)malloc(sizeof(struct slist)); head = p; p ->data = 10; q ->data = 20; p ->next = q; q ->next =NULL; //表尾插入一个节点 node = 30 struct slist *n = head; //求尾节点位置 while(n ->next != NULL) { n = n ->next; } struct slist *node = (struct slist*)malloc(sizeof(struct slist)); node ->data = 30; n ->next = node; node ->next = NULL; //输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); free(p); free(node); }
将数组中的元素逐一插入到链表中
#include <stdio.h> #include <stdlib.h> //Definition for singly-linked list. struct ListNode { int val; struct ListNode *next; }; //打印链表 void print_list(struct ListNode *list) { struct ListNode *p=list; while(p!=NULL) { printf("%d ",p->val); p=p->next; } printf("\n"); } //由数组构建链表 struct ListNode* insert(int *li) { int length=sizeof(li)/sizeof(li[0])+1; struct ListNode *head=NULL,*temp,*last;//head为链表的头指针,temp为指向当前访问节点的指针 for(int i=0;i<length;i++) { //为新插入的节点申请空间 temp=(struct ListNode *)malloc(sizeof(struct ListNode)); temp->val=li[i]; //首次插入时 if(head==NULL) { head=temp; temp->next=NULL; last=temp; }else{ //尾插法 last->next=temp; temp->next=NULL; last=temp; } } return head; } int main() { int l1[] = {1,2,4}, l2[] = {1,3,4}; struct ListNode *list1=NULL,*list2=NULL; //数组转链表 list1=insert(l1); list2=insert(l2); print_list(list1); print_list(list2); return 0; }
删除结点
删除链表中元素17后面的元素80
#include <stdio.h> #include <stdlib.h> //单链表定义 struct slist { int data; struct slist *next; }; // 删除链表中元素17后面的元素80 void main() { // 建立链表 int i,a[8] = {35,46,17,80,25,78,66,54}; struct slist *head = NULL,*p,*q; // head为链表的头指针,p为指向当前访问节点的指针 for(i = 0;i < 8;i++) { //为新插入节点申请存储空间 q = (struct slist *)malloc(sizeof(struct slist)); q -> data = a[i]; // 第一个插入时 if(head == NULL) { head = q; q ->next = NULL; p = q; } //后续插入 else { p ->next = q; q ->next = NULL; p = q; } } //删除链表中元素17后面的元素80 p = head; //找到17的位置,并用p指向17 while(p ->data != 17) { p = p ->next; } struct slist *temp; temp = p ->next; p ->next = p ->next ->next; free(temp); //将temp指向的存储空间释放 // 打印输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); }
删除表头
#include <stdio.h> #include <stdlib.h> //单链表定义 struct slist { int data; struct slist *next; }; // 删除表头元素 void main() { // 建立链表 int i,a[8] = {35,46,17,80,25,78,66,54}; struct slist *head = NULL,*p,*q; // head为链表的头指针,p为指向当前访问节点的指针 for(i = 0;i < 8;i++) { //为新插入节点申请存储空间 q = (struct slist *)malloc(sizeof(struct slist)); q -> data = a[i]; // 第一个插入时 if(head == NULL) { head = q; q ->next = NULL; p = q; } //后续插入 else { p ->next = q; q ->next = NULL; p = q; } } //删除表头 p = head; head = head ->next; free(p); // 打印输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); }
删除表尾元素
#include <stdio.h> #include <stdlib.h> //单链表定义 struct slist { int data; struct slist *next; }; // 删除表尾元素 void main() { // 建立链表 int i,a[8] = {35,46,17,80,25,78,66,54}; struct slist *head = NULL,*p,*q; // head为链表的头指针,p为指向当前访问节点的指针 for(i = 0;i < 8;i++) { //为新插入节点申请存储空间 q = (struct slist *)malloc(sizeof(struct slist)); q -> data = a[i]; // 第一个插入时 if(head == NULL) { head = q; q ->next = NULL; p = q; } //后续插入 else { p ->next = q; q ->next = NULL; p = q; } } //删除表尾 //【假设不知道p本就指向表尾】 p = head; struct slist *temp; //找到表尾前一个位置 while(p ->next ->next != NULL) { p = p ->next; } temp = p ->next; p ->next = NULL; free(temp); //释放temp指向的空间 // 打印输出 struct slist *cp = head; while(cp != NULL) { printf("%d\n",cp -> data); cp = cp -> next; } free(q); }
建立单链表
头插法
#include <stdio.h> #include <stdlib.h> //单链表定义 typedef struct slist { int data; struct slist *next; }; struct slist *L; //L为头结点 //建立单链表【头插法】 void creatlist1() { //从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素 struct slist *s; int x; L = (struct slist *)malloc(sizeof(struct slist)); // L为头结点 L ->next = NULL; //初始为空链表 printf("请输入元素:"); scanf("%d",&x); while(x != 9999) //输入9999表示结束 { s = (struct slist *)malloc(sizeof(struct slist)); //创建新链表 s ->data = x; s ->next = L ->next; //将新结点插入表中 L ->next = s; printf("请输入元素:"); scanf("%d",&x); } } //输出 void outlist() { struct slist * cp; cp = L ->next; //头结点不存数据 while(cp != NULL) { printf("%d",cp ->data); printf("->"); cp = cp ->next; } printf("NULL"); } //建立单链表 void main() { creatlist1(); printf("单链表如下:\n"); outlist(); }
尾插法
#include <stdio.h> #include <stdlib.h> //单链表定义 typedef struct slist { int data; struct slist *next; }; struct slist *L; //L为头结点 //建立单链表【尾插法】 void creatlist2() { //从表尾到表头正向建立单链表L,每次均在表尾之后插入元素 struct slist *s,*r; int x; L = (struct slist *)malloc(sizeof(struct slist)); // L为头结点 r = L; //r是尾指针 printf("请输入元素:"); scanf("%d",&x); while(x != 9999) //输入9999表示结束 { s = (struct slist *)malloc(sizeof(struct slist)); //创建新链表 s ->data = x; r ->next = s; //将新结点插入表中 r = s; printf("请输入元素:"); scanf("%d",&x); } r ->next = NULL; // 尾结点指针置空 } //输出 void outlist() { struct slist * cp; cp = L ->next; //头结点不存数据 while(cp != NULL) { printf("%d",cp ->data); printf("->"); cp = cp ->next; } printf("NULL"); } //建立单链表 void main() { creatlist2(); printf("单链表如下:\n"); outlist(); }
查找
按序号查找值
#include <stdio.h> #include <stdlib.h> //单链表定义 typedef struct slist { int data; struct slist *next; }; struct slist *L; //L为头结点 //建立单链表【尾插法】 void creatlist2() { //从表尾到表头正向建立单链表L,每次均在表尾之后插入元素 struct slist *s,*r; int x; L = (struct slist *)malloc(sizeof(struct slist)); // L为头结点 r = L; //r是尾指针 printf("请输入元素:"); scanf("%d",&x); while(x != 9999) //输入9999表示结束 { s = (struct slist *)malloc(sizeof(struct slist)); //创建新链表 s ->data = x; r ->next = s; //将新结点插入表中 r = s; printf("请输入元素:"); scanf("%d",&x); } r ->next = NULL; // 尾结点指针置空 } //按序号查找结点值 void getelem(int i) { //取单链表L(带头结点)中第i个位置的结点指针 int j = 1; struct slist *p = L ->next; //头结点无值 if(i < 1) printf("NULL"); // 若i无效,则返回NULL while(p ->data && j < i) { p = p ->next; j++; } printf("%d\n",p ->data); } //输出 void outlist() { struct slist * cp; cp = L ->next; //头结点不存数据 while(cp != NULL) { printf("%d",cp ->data); printf("->"); cp = cp ->next; } printf("NULL\n"); } //建立单链表 void main() { int i; creatlist2(); printf("单链表如下:\n"); outlist(); printf("查找第几个元素:"); scanf("%d",&i); getelem(i); }
按值查找
#include <stdio.h> #include <stdlib.h> //单链表定义 typedef struct slist { int data; struct slist *next; }; struct slist *L; //L为头结点 //建立单链表【尾插法】 void creatlist2() { //从表尾到表头正向建立单链表L,每次均在表尾之后插入元素 struct slist *s,*r; int x; L = (struct slist *)malloc(sizeof(struct slist)); // L为头结点 r = L; //r是尾指针 printf("请输入元素:"); scanf("%d",&x); while(x != 9999) //输入9999表示结束 { s = (struct slist *)malloc(sizeof(struct slist)); //创建新链表 s ->data = x; r ->next = s; //将新结点插入表中 r = s; printf("请输入元素:"); scanf("%d",&x); } r ->next = NULL; // 尾结点指针置空 } //按值查找表结点 void getelem(int elem) { //查找单链表L(带头结点)中数据等于elem的结点指针,返回位置,否则返回NULL struct slist *p = L ->next; //头结点无值,从第一个结点开始 int j = 1; while(p != NULL && p ->data != elem) { p = p ->next; j++; } printf("%d\n",j); } //输出 void outlist() { struct slist * cp; cp = L ->next; //头结点不存数据 while(cp != NULL) { printf("%d",cp ->data); printf("->"); cp = cp ->next; } printf("NULL\n"); } //建立单链表 void main() { int elem; creatlist2(); printf("单链表如下:\n"); outlist(); printf("查找元素是:"); scanf("%d",&elem); getelem(elem); }
合并
两个有序链表合并(带重复值)
方法1:逐个比较
#include <stdio.h> #include <stdlib.h> //Definition for singly-linked list. struct ListNode { int val; struct ListNode *next; }; //打印链表 void print_list(struct ListNode *list) { struct ListNode *p=list; while(p!=NULL) { printf("%d ",p->val); p=p->next; } printf("\n"); } //由数组构建链表 struct ListNode* insert(int *li) { int length=sizeof(li)/sizeof(li[0])+1; struct ListNode *head=NULL,*temp,*last;//head为链表的头指针,temp为指向当前访问节点的指针 for(int i=0;i<length;i++) { //为新插入的节点申请空间 temp=(struct ListNode *)malloc(sizeof(struct ListNode)); temp->val=li[i]; //首次插入时 if(head==NULL) { head=temp; temp->next=NULL; last=temp; }else{ //尾插法 last->next=temp; temp->next=NULL; last=temp; } } return head; } struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){ struct ListNode *list,*node;//list为链表的头指针 list=(struct ListNode*) malloc(sizeof(struct ListNode));//头节点 node=list; while(list1!=NULL && list2!=NULL) { if(list1->val < list2->val) { node->next=list1; node=node->next; list1=list1->next; }else { node->next=list2; node=node->next; list2=list2->next; } } //如果有一个为空,则直接链接另外一条 if(list1==NULL) { node->next=list2; }else { node->next=list1; } return list->next; } int main() { int l1[] = {1,2,4}, l2[] = {1,3,4}; struct ListNode *list1=NULL,*list2=NULL,*list3=NULL; //数组转链表 list1=insert(l1); list2=insert(l2); print_list(list1); print_list(list2); //链表合并(升序) list3=mergeTwoLists(list1,list2); print_list((list3)); return 0; }
方法2递归:
#include <stdio.h> #include <stdlib.h> //Definition for singly-linked list. struct ListNode { int val; struct ListNode *next; }; //打印链表 void print_list(struct ListNode *list) { struct ListNode *p=list; while(p!=NULL) { printf("%d ",p->val); p=p->next; } printf("\n"); } //由数组构建链表 struct ListNode* insert(int *li) { int length=sizeof(li)/sizeof(li[0])+1; struct ListNode *head=NULL,*temp,*last;//head为链表的头指针,temp为指向当前访问节点的指针 for(int i=0;i<length;i++) { //为新插入的节点申请空间 temp=(struct ListNode *)malloc(sizeof(struct ListNode)); temp->val=li[i]; //首次插入时 if(head==NULL) { head=temp; temp->next=NULL; last=temp; }else{ //尾插法 last->next=temp; temp->next=NULL; last=temp; } } return head; } struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){ if(list1==NULL) return list2; if(list2==NULL) return list1; if(list1->val <list2->val) { list1->next= mergeTwoLists(list1->next,list2); return list1; } else { list2->next= mergeTwoLists(list1,list2->next); return list2; } } int main() { int l1[] = {1,2,4}, l2[] = {1,3,4}; struct ListNode *list1=NULL,*list2=NULL,*list3=NULL; //数组转链表 list1=insert(l1); list2=insert(l2); print_list(list1); print_list(list2); //链表合并(生序) list3=mergeTwoLists(list1,list2); print_list((list3)); return 0; }
双向链表
构建双向链表
#include <stdio.h> #include <stdlib.h> //双向链表定义 typedef struct dlist { int data; struct dlist *next; struct dlist *prior; }; struct dlist *head; //L 为头结点 //构建双向链表 void creatdlist() { struct dlist *p,*q; head =(struct dlist *)malloc(sizeof(struct dlist)); head ->prior = NULL; head ->next = NULL; q = head; int x; printf("请输入元素:"); scanf("%d",&x); while(x != 9999) { p =(struct dlist *)malloc(sizeof(struct dlist)); p ->data =x; p ->next = q ->next; p ->prior = q; q ->next = p; q = p; printf("请输入元素:"); scanf("%d",&x); } } //输出 void outdlist() { struct dlist * cp; //指向当前结点 cp = head ->next; //头结点不存数据 while(cp != NULL) { printf("%d\t",cp ->data); cp = cp ->next; } } void main() { creatdlist(); outdlist(); }
插入
在指定的链表元素后插入给定的元素
#include <stdio.h> #include <stdlib.h> //双向链表定义 typedef struct dlist { int data; struct dlist *next; struct dlist *prior; }; struct dlist *head; //L 为头结点 //构建双向链表 void creatdlist() { struct dlist *p,*q; head =(struct dlist *)malloc(sizeof(struct dlist)); head ->prior = NULL; head ->next = NULL; q = head; int x; printf("请输入元素:"); scanf("%d",&x); while(x != 9999) { p =(struct dlist *)malloc(sizeof(struct dlist)); p ->data =x; p ->next = q ->next; p ->prior = q; q ->next = p; q = p; printf("请输入元素:"); scanf("%d",&x); } } //输出 void outdlist() { struct dlist * cp; //指向当前结点 cp = head ->next; //头结点不存数据 while(cp != NULL) { printf("%d\t",cp ->data); cp = cp ->next; } } //在指定的链表元素后插入给定的元素 void indlist(int n,int temp) { struct dlist *dp,*node; //指向当前结点 dp = head ->next; node = (struct dlist *)malloc(sizeof(struct dlist)); node ->data = temp; //找到元素n的位置,cp指向 while(dp ->data != n) { dp = dp ->next; } //插入 node ->next = dp ->next; //1 dp ->next ->prior = node; //2 node ->prior = dp; //3 dp ->next = node; //4 } void main() { int n,temp; creatdlist(); outdlist(); printf("\n指定在谁后插入:"); scanf("%d",&n); printf("\n插入元素为:"); scanf("%d",&temp); indlist(n,temp); printf("插入后链表:\n"); outdlist(); }
在指定的链表元素前插入给定的元素
#include <stdio.h> #include <stdlib.h> //双向链表定义 typedef struct dlist { int data; struct dlist *next; struct dlist *prior; }; struct dlist *head; //L 为头结点 //构建双向链表 void creatdlist() { struct dlist *p,*q; head =(struct dlist *)malloc(sizeof(struct dlist)); head ->prior = NULL; head ->next = NULL; q = head; int x; printf("请输入元素:"); scanf("%d",&x); while(x != 9999) { p =(struct dlist *)malloc(sizeof(struct dlist)); p ->data =x; p ->next = q ->next; p ->prior = q; q ->next = p; q = p; printf("请输入元素:"); scanf("%d",&x); } } //输出 void outdlist() { struct dlist * cp; //指向当前结点 cp = head ->next; //头结点不存数据 while(cp != NULL) { printf("%d\t",cp ->data); cp = cp ->next; } } //在指定的链表元素前插入给定的元素 void indlist(int n,int temp) { struct dlist *dp,*node; //指向当前结点 dp = head ->next; node = (struct dlist *)malloc(sizeof(struct dlist)); node ->data = temp; //找到元素n的位置,cp指向 while(dp ->data != n) { dp = dp ->next; } //插入 node ->next = dp; //1 node ->prior = dp ->prior; //2 dp ->prior ->next = node; //3 dp ->prior = node; //4 } void main() { int n,temp; creatdlist(); outdlist(); printf("\n指定在谁前插入:"); scanf("%d",&n); printf("\n插入元素为:"); scanf("%d",&temp); indlist(n,temp); printf("插入后链表为:\n"); outdlist(); }
删除
#include <stdio.h> #include <stdlib.h> //双向链表定义 typedef struct dlist { int data; struct dlist *next; struct dlist *prior; }; struct dlist *head; //L 为头结点 //构建双向链表 void creatdlist() { struct dlist *p,*q; head =(struct dlist *)malloc(sizeof(struct dlist)); head ->prior = NULL; head ->next = NULL; q = head; int x; printf("请输入元素:"); scanf("%d",&x); while(x != 9999) { p =(struct dlist *)malloc(sizeof(struct dlist)); p ->data =x; p ->next = q ->next; p ->prior = q; q ->next = p; q = p; printf("请输入元素:"); scanf("%d",&x); } } //输出 void outdlist() { struct dlist * cp; //指向当前结点 cp = head ->next; //头结点不存数据 while(cp != NULL) { printf("%d\t",cp ->data); cp = cp ->next; } } //删除指定的链表元素 void dedlist(int temp) { struct dlist *dp; dp = head ->next; //找到temp的位置,并dp指向 while(dp ->data != temp) { dp = dp ->next; } //删除 dp ->prior ->next = dp ->next; dp ->next ->prior = dp ->prior; free(dp); } void main() { int temp; creatdlist(); outdlist(); printf("\n删除元素为:"); scanf("%d",&temp); dedlist(temp); printf("删除后链表为:\n"); outdlist(); }