第一题(链表中递归删除元素x)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
void Delete_x(LNode *P,LNode *C,Elemtype e)
{
if(C==NULL)return;
if(C->data==e)
{
P->next=C->next;
free(C);
Delete_x(P,P->next,e);
}
else
{
Delete_x(C,C->next,e);
}
}
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
int main()
{
LinkList L;
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("请输入删除指定元素:");
int x;
scanf("%d",&x);
Delete_x(L,L->next,x);
PrintLinkList(L);
return 0;
}
第二题(删除链表中值为x的结点)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
void Delete_x(LinkList L,Elemtype e)
{
LNode *p=L->next,*prv=L,*q;
while(p!=NULL)
{
if(p->data==e)
{
q=p;
p=p->next;
prv->next=p;
free(q);//释放q的空间,交给操作系统
}
else
{
prv=prv->next;
p=p->next;
}
}
}
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("请输入删除指定元素:");
int x;
scanf("%d",&x);
Delete_x(L,x);
PrintLinkList(L);
return 0;
}
第三题(递归反向打印链表)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
void Reverse_Print(LinkList L)
{
if(L==NULL)return ;
Reverse_Print(L->next);
printf("%d--->",L->data);
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
printf("正向打印\n");
PrintLinkList(L);
printf("反向打印\n");
Reverse_Print(L->next);
return 0;
}
第四题(遍历链表删除链表中最小元素)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList Del_Min(LinkList L)
{
LNode *p=L->next,*pre=L,*minp=p,*minpre=pre;//p为前序结点,t为最小结点,tp为最小结点的前序结点,r用于遍历
while(p)
{
if(minp->data>p->data)
{
minp=p;
minpre=pre;
}
pre=p;
p=p->next;
}
minpre->next=minp->next;
free(minp);
return L;
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("删除最小结点\n");
L=Del_Min(L);
PrintLinkList(L);
return 0;
}
第五题(链表逆转)
使用头插法逆转,或者直接改变指针方向
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
/*
使用头插法逆转链表
*/
LinkList Reverse_1(LinkList L)
{
LNode *p=L->next,*r; //p为插入元素,r为p的下一个元素
L->next=NULL;
while(p)
{
r=p->next;
p->next=L->next;
L->next=p;
p=r;
}
return L;
}
/*
直接逆转指针法
*/
LinkList Reverse_2(LinkList L)
{
LNode *pre,*p=L->next,*r=p->next;
p->next=NULL;//p变为最后一个结点
while(r!=NULL)
{
pre=p;//后移动
p=r;
r=r->next;
p->next=pre;//改变指针
}
L->next=p;
return L;
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("头插法链表逆转\n");
L=Reverse_1(L);
PrintLinkList(L);
printf("直接改变方向链表逆转\n");
L=Reverse_2(L);
PrintLinkList(L);
return 0;
}
第六题(插入排序,给链表排序)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
//插入排序
void Sort(LinkList L)
{
LNode *pre,*p=L->next,*r=p->next; //pre用于找到合适位置,p当前需要排序的元素,r方便p向后移动
p->next=NULL;//将头节点和首结点断开,整个链表分两段,前一段有序,后一段无序
p=r;
while(p!=NULL)
{
r=p->next;
pre=L;//开始向后找到p合适位置(从小到大排序)
while(pre->next!=NULL&&pre->next->data<p->data)pre=pre->next;
p->next=pre->next;
pre->next=p;
p=r;//继续新的p
}
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("从小到大排序\n");
Sort(L);
PrintLinkList(L);
return 0;
}
第七题(删除s到t之间的结点)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
void Del_s_t(LinkList L,int s,int t)
{
LNode *p=L->next,*pre=L;
while(p!=NULL)
{
if(p->data<t&&p->data>s)
{
pre->next=p->next;
free(p);
p=pre->next;
}
else
{
pre=p;
p=p->next;
}
}
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
Del_s_t(L,1,4);
PrintLinkList(L);
return 0;
}
第八题(链表公共部分)
两个链表公共部分,只要某个结点相同,则后面一定都相同,这里的相同不仅仅指元素相同,更是指两个指针指向同一个结点,所以只要找到第一个相同指向的结点,后面一定都相同!
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
//单链表
typedef struct LNode
{
Elemtype data;//存放数据
struct LNode *next; //指向LNode的一个指针
} LNode,*LinkList; //相当于取别名,LNode代表一个节点,LinkList代表整个单链表(指向LNode的一个指针)
void PrintList(LinkList L)
{
LinkList p;
p=L->next;//找到头指针指向节点,开始遍历
printf("链表元素如下:\n");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int GetLen(LinkList L)
{
LinkList p;
p=L;
int len=0;
while(p!=NULL)
{
p=p->next;
len++;
}
return len;
}
//尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
//创建共同结点
void Create_Common(LinkList L1,LinkList L2)
{
LNode *p=L1->next,*q=L2->next;
while(p->next!=NULL)
{
p=p->next;
}
while(q->next!=NULL)
{
q=q->next;
}
int x;
printf("请输入共同结点元素值:\n");
scanf("%d",&x);
LNode *s=(LNode*)malloc(sizeof(LNode));
s->data=x;
p->next=s;
q->next=s;
s->next=NULL;
}
//寻找共同结点
LinkList Search_lst_Common(LinkList L1,LinkList L2)
{
int len1=GetLen(L1),len2=GetLen(L2);
int dist;
LinkList longList,shortList;
//比较链表长短
if(len1>len2)
{
longList=L1->next;
shortList=L2->next;
dist=len1-len2;
}
else
{
longList=L2->next;
shortList=L1->next;
dist=len2-len1;
}
//将长链表遍历到和短链表相同长度
while(dist--)
{
longList=longList->next;
}
while(longList!=NULL)
{
if(longList==shortList)return longList;//找到共同结点
else
{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;//没找到返回NULL
}
int main()
{
LinkList L1,L2;//使用头插法 这里的L就是一个头指针
printf("请输入链表元素,输入9999表示结束\n");
L1=List_TailInsert(L1); // 1 2 3 4
PrintList(L1);
printf("请输入链表元素,输入9999表示结束\n");
L2=List_TailInsert(L2);
PrintList(L2);
//创建共同结点
Create_Common(L1,L2);
printf("找到共同结点\n");
LNode *p=Search_lst_Common(L1,L2);//共同结点
printf("当前结点值为:%d",p->data);
return 0;
}
第九题(依次删除最小元素O(n^2))
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
//每次找到最小结点,然后删除,以此类推直到链表为空
void Min_Delete(LinkList L)
{
while(L->next!=NULL)
{
LNode *pre=L;//记录前驱结点,为了删除
LNode *p=L->next;
while(p->next!=NULL)
{
if(p->next->data<p->data)
{
pre=p;
}
p=p->next;
}
printf("%d ",pre->next->data);
LNode *t=pre->next;
pre->next=t->next;
free(t);
}
free(L);
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
Min_Delete(L);
return 0;
}
第十题(链表拆分)
新建两个链表A、B分别将原来的链表拆分,赋给A、B链表,采用尾插法
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
int GetLength(LinkList L)
{
LNode *p=L->next;
int len=0;
while(p)
{
p=p->next;
len++;
}
return len;
}
//相当于把原来的链表进行拆分,为A、B链表
LinkList DisCreate_L(LinkList A)
{
LinkList B=(LinkList)malloc(sizeof(LNode));//创建B链表
B->next=NULL;
LNode *ra=A,*rb=B,*p;//使用尾插法
p=A->next;
A->next=NULL;//将A链断开,重新添元素
int i=0;
while(p!=NULL)
{
i++;
if(i%2==0)
{
rb->next=p;
rb=p;
}
else
{
ra->next=p;
ra=p;
}
p=p->next;
}
ra->next=NULL;
rb->next=NULL;
return B;
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("拆分为奇数链表和偶数链表\n");
LinkList B;
B=DisCreate_L(L);
PrintLinkList(L);
PrintLinkList(B);
return 0;
}
第十一题(链表原地拆分)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList DisCreat_L(LinkList A)
{
LinkList B=(LinkList)malloc(sizeof(LNode));
B->next=NULL;
LNode *p=A->next,*q;//初使时p在应该断开B的结点的前一个结点,q为p的一下结点,由于p后面会和A断开,故q用来保存p下一轮循环的位置
LNode *ra=A;//ra为p的前一个结点,防止A断链,每次需要将ra.next指向p
while(p!=NULL)
{
ra->next=p,ra=p;//ra先防止断链,然后移动到下一次工作位置也就是当前p的位置
p=p->next;//p移动到应该断开的b结点
if(p!=NULL)
{
q=p->next;//q存储b结点后的a结点
p->next=B->next;//头插法
B->next=p;
p=q;//p移动到一下次工作位置
}
}
ra->next=NULL;//将A的尾结点置空
return B;
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("拆分链表\n");
LinkList B;
B=DisCreat_L(L);
PrintLinkList(L);
PrintLinkList(B);
return 0;
}
第十二题(删除链表中重复元素)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList Del_Same(LinkList L)
{
LNode *p=L->next,*q; //两个指针不断移动
if(p==NULL)return;
while(p->next!=NULL)
{
q=p->next;
if(p->data==q->data)
{
p->next=q->next;
free(q);
}
else
{
p=p->next;
}
}
return L;
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
printf("删除重复元素\n");
LinkList B;
B=Del_Same(L);
PrintLinkList(L);
return 0;
}
第十三题(将两个递增链表转换为一个递减链表)
类似于Merge操作,需要就地完成,代码里有一些操作值得学习
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList Merge_List(LinkList A,LinkList B)
{
LNode *p=A->next,*q=B->next;
A->next=NULL;//将A重新安排
while(p!=NULL&&q!=NULL)
{
LNode *s;//s作为暂存结点
if(p->data<q->data)
{
s=p;
p=p->next;
s->next=A->next;
A->next=s;//头插法
}
else
{
s=q;
q=q->next;
s->next=A->next;
A->next=s;
}
}
if(p!=NULL) //A链表还有多余元素
{
q=p;//赋给q
}
while(q!=NULL)
{
LNode *s;
s=q;
q=q->next;
s->next=A->next;
A->next=s;
}
free(B);//将B的空间释放
return A;
}
int main()
{
LinkList A,B;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
A=List_TailInsert(A);
PrintLinkList(A);
printf("创建链表,输入链表的值 9999表示结束!\n");
B=List_TailInsert(B);
PrintLinkList(B);
printf("递减合并链表\n");
LinkList C;
C=Merge_List(A,B);
PrintLinkList(C);
return 0;
}
第十四题(两个递增链表,找出共同元素)
采用双指针法,不同则指针移动,相同则添加进入新链表
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList Get_Common(LinkList A,LinkList B)
{
LNode *p=A->next,*q=B->next;
LinkList C=(LinkList)malloc(sizeof(LNode));
LNode *r=C,*s;//尾插法
while(p!=NULL&&q!=NULL)
{
if(p->data<q->data)
{
p=p->next;
}else if(p->data>q->data)
{
q=q->data;
}else{
s=(LNode*)malloc(sizeof(LNode));
s->data=p->data;//复制产生s结点
r->next=s;
r=s; //尾插法,r向后移动
p=p->next;
q=q->next;
}
}
r->next=NULL;//最后一个结点指向空
return C;
}
int main()
{
LinkList A,B;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
A=List_TailInsert(A);
PrintLinkList(A);
printf("创建链表,输入链表的值 9999表示结束!\n");
B=List_TailInsert(B);
PrintLinkList(B);
printf("找出共同元素\n");
LinkList C;
C=Get_Common(A,B);
PrintLinkList(C);
return 0;
}
第十五题(两个递增链表找出共同元素,不准新开链表C)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
//不开新链表找出交集,并将另外的链表释放
LinkList Union(LinkList A,LinkList B)
{
LNode *pa=A->next,*pb=B->next;
LNode *pc=A;
LNode *s;
while(pa!=NULL&&pb!=NULL)
{
if(pa->data==pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
s=pb;
pb=pb->next;
free(s);
}
else if(pa->data<pb->data) //a<b时,释放a结点
{
s=pa;
pa=pa->next;
free(s);
}
else
{
s=pb;
pb=pb->next;
free(s);
}
}
while(pa)
{
s=pa;
pa=pa->next;
free(s);
}
while(pb)
{
s=pb;
pb=pb->next;
free(s);
}
pc->next=NULL;
free(B);//释放B的头节点
return A;
}
int main()
{
LinkList A,B;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
A=List_TailInsert(A);
PrintLinkList(A);
printf("创建链表,输入链表的值 9999表示结束!\n");
B=List_TailInsert(B);
PrintLinkList(B);
printf("找出共同元素\n");
LinkList C;
C=Union(A,B);
PrintLinkList(C);
return 0;
}
第十六题(判断是否为子序列问题)
从A的每个结点开始向后遍历,如果从该结点,向后的序列和B匹配则(一直到遍历到B结束),返回1,否则返回0
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=NULL)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
//不开新链表找出交集,并将另外的链表释放
bool Pattern(LinkList A,LinkList B)
{
LNode *p=A->next;
LNode *q=B->next;
LNode *pre=p;
while(p&&q)
{
if(p->data==q->data)
{
p=p->next;
q=q->next;
}
else
{
pre=pre->next; //从pre的下一个结点继续开始寻找
p=pre;
q=B->next; //B从头开始匹配
}
}
if(q==NULL) //q已经在末尾了,说明肯定匹配成功
{
return 1;
}
return 0;
}
int main()
{
LinkList A,B;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
A=List_TailInsert(A);
PrintLinkList(A);
printf("创建链表,输入链表的值 9999表示结束!\n");
B=List_TailInsert(B);
PrintLinkList(B);
printf("B是否为A的子序列 %d\n",Pattern(A,B));
return 0;
}
第十七题(判断双向循环链表是否对称)
注意中止条件,当链表有奇数个结点时,中止条件为pq,当链表有偶数个结点时,终止条件为p->nextq
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct DNode{
Elemtype data;
struct DNode *prior,*next;
}DNode,*DLinkList;
DLinkList CreateList()
{
int x;
//双向循环链表初始化
DLinkList head=(DLinkList)malloc(sizeof(DNode));
head->next=head;
head->prior=head;
scanf("%d",&x);
DNode *p=head->prior,*s;//P尾结点,s为新结点
while(x!=9999)
{
s=(DNode*)malloc(sizeof(DNode));
s->data=x;
//尾结点和新结点连在一起
p->next=s;
s->prior=p;
//新结点和头节点连在一起
s->next=head;
head->prior=s;
p=s;
scanf("%d",&x);
}
return head;
}
void PrintDList(DLinkList L)
{
DNode *p=L->next;
while(p!=L)
{
printf("%d<---->",p->data);
p=p->next;
}
}
bool Is_Symmetry(DLinkList L)
{
DNode *p=L->next;
DNode *q=L->prior;
while(p!=q&&p->next!=q)//第一个中止条件为结点个数是奇数情况下,第二个中止条件为结点个数是偶数条件下
{
if(p->data!=q->data)return false;
p=p->next;
q=q->prior;
}
return true;
}
int main()
{
DLinkList L;
printf("请创建双向列表,输入9999表示结束\n");
L=CreateList();
PrintDList(L);
printf("是否对称:%d",Is_Symmetry(L));
return 0;
}
第十八题(连接两个单循环链表)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=L;
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=L)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
LinkList Link(LinkList L1,LinkList L2)
{
LNode *p=L1;
while(p->next!=L1)
{
p=p->next;
}
LNode *q=L2;
while(q->next!=L2)
{
q=q->next;
}
p->next=L2->next;//把L2链接到L1上
free(L2);
q->next=L1;//把L2的尾结点指针指向L1的头结点
return L1;
}
int main()
{
LinkList A,B;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
A=List_TailInsert(A);
PrintLinkList(A);
printf("创建链表,输入链表的值 9999表示结束!\n");
B=List_TailInsert(B);
PrintLinkList(B);
LinkList C=L_L(A,B);
PrintLinkList(C);
return 0;
}
第十九题(每次删除链表中最小元素,直到链表为空)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
typedef struct LNode
{
Elemtype data;
struct LNode *next;
} LNode,*LinkList;
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LinkList));//创建头节点
L->next=NULL;
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode*));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=L;
return L;
}
void PrintLinkList(LinkList L)
{
printf("打印链表\n");
LNode *r=L->next;
while(r!=L)
{
printf("%d--->",r->data);
r=r->next;
}
printf("\n");
}
void Del_All_Min(LinkList L)
{
LNode *p,*pre,*minp,*minpre;
while(L->next!=L)
{
p=L->next;
pre=L;
minp=p;
minpre=pre;
while(p!=L)
{
if(p->data<minp->data)
{
minp=p;
minpre=pre;
}
p=p->next;
pre=pre->next;
}
printf("删除最小元素:%d\n",minp->data);
minpre->next=minp->next;
free(minp);
}
free(L);//释放头节点
}
int main()
{
LinkList L;//头指针,创建链表
printf("创建链表,输入链表的值 9999表示结束!\n");
L=List_TailInsert(L);
PrintLinkList(L);
Del_All_Min(L);
return 0;
}
第二十一题(判断单链表是否环化)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
//单链表
typedef struct LNode
{
Elemtype data;//存放数据
struct LNode *next; //指向LNode的一个指针
} LNode,*LinkList; //相当于取别名,LNode代表一个节点,LinkList代表整个单链表(指向LNode的一个指针)
void PrintList(LinkList L)
{
LinkList p;
p=L->next;//找到头指针指向节点,开始遍历
printf("链表元素如下:\n");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=L->next; //使环化
return L;
}
LNode* FindLoopStart(LinkList L)
{
LNode *fast=L->next;
LNode *slow=L->next; //设置快慢指针
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;//slow每次走一步
fast=fast->next->next;//fast每次走两步
if(slow==fast)break;
}
if(slow==NULL||fast->next==NULL)return NULL;//没有环
LNode *p1=L->next,*p2=slow;
while(p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
return p1; //返回入口点
}
int main()
{
LinkList L;
printf("创建链表,输入9999创建结束!\n");
L=List_TailInsert(L); //尾插法更改尾结点使得环化,入口结点为首结点
printf("环的入口结点为 %d",FindLoopStart(L)->data);
return 0;
}
第二十二题(寻找倒数第K个结点,只能遍历一次链表)
采用双指针,一个指针向前走k步,后面指针在开始走,这样前面指针到达尾部,后指针到达第k个位置
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
//单链表
typedef struct LNode
{
Elemtype data;//存放数据
struct LNode *next; //指向LNode的一个指针
} LNode,*LinkList; //相当于取别名,LNode代表一个节点,LinkList代表整个单链表(指向LNode的一个指针)
void PrintList(LinkList L)
{
LinkList p;
p=L->next;//找到头指针指向节点,开始遍历
printf("链表元素如下:\n");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//头插法建立链表 (打印倒叙打印)
LinkList List_HeadInsert(LinkList L)
{
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));//创建头节点
L->next=NULL;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));//创建新节点
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
//尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL; //使环化
return L;
}
//寻找第倒数第k个元素,双指针只需要遍历一遍
int Search_k(LinkList L,int k)
{
LNode *p=L->next,*q=L->next;
int count=0;
while(p!=NULL) //这里是!=NULL,如果使p->next!=NULL,count从1开始
{
if(count<k)count++;
else q=q->next;
p=p->next;
}
if(count<k)return 0;
else
{
printf("%d",q->data);
}
return 1;
}
int main()
{
LinkList L;
printf("创建链表,输入9999创建结束!\n");
L=List_TailInsert(L); //尾插法更改尾结点使得环化,入口结点为首结点
Search_k(L,3);
return 0;
}
第二十三题(寻找相同后缀)
LNode* Find_Addr(LinkList L1,LinkList L2)
{
int m,n; //取m最大
m=GetLen(L1);
n=GetLen(L2);
LNode *p,*q; //p指向链表长的链,q指向短链
for(p=L1;m>n;m--)
{
p=p->next;
}
for(q=L2;m<n;n--)
{
q=q->next;
}
while(p->next!=NULL&&p->next!=q->next)
{
p=p->next;
q=q->next;
}
return p->next;
}
第二十四题(利用散列表删除数组中重复元素)
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
//单链表
typedef struct LNode
{
Elemtype data;//存放数据
struct LNode *next; //指向LNode的一个指针
} LNode,*LinkList; //相当于取别名,LNode代表一个节点,LinkList代表整个单链表(指向LNode的一个指针)
void PrintList(LinkList L)
{
LinkList p;
p=L->next;//找到头指针指向节点,开始遍历
printf("链表元素如下:\n");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList Del_Same(LinkList L,Elemtype n)
{
LNode *pre=L,*r=L->next;//pre表示前一个结点,r用于遍历当前结点
int *vis,m;
vis=(int*)malloc(sizeof(int)*(n+1));
for(int i=0;i<=n;i++)
{
vis[i]=0;
}
while(r!=NULL)
{
m=r->data>0?r->data:-r->data;
if(vis[m]==0)
{
vis[m]=1;//标记
pre=r;
r=r->next;
}else{
//需要删除
pre->next=r->next;
LNode *s=r;
r=r->next;
free(s);//删除当前结点
}
}
free(vis);//归还数组空间
return L;
}
int main()
{
LinkList L;//使用头插法 这里的L1就是一个头指针
printf("请输入链表元素,输入9999表示结束\n");
L=List_TailInsert(L); // 1 2 3 4
PrintList(L);
printf("删除数组中重复元素\n");
L=Del_Same(L,10);
PrintList(L);
return 0;
}
第二十五题(链表逆转+找到第k个结点+链表交换结点)
这道题考的非常全面,非常值得学习
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef int Elemtype;
//单链表
typedef struct LNode
{
Elemtype data;//存放数据
struct LNode *next; //指向LNode的一个指针
} LNode,*LinkList; //相当于取别名,LNode代表一个节点,LinkList代表整个单链表(指向LNode的一个指针)
void PrintList(LinkList L)
{
LinkList p;
p=L->next;//找到头指针指向节点,开始遍历
printf("链表元素如下:\n");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *r=L,*s;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
LinkList Change_List(LinkList L)
{
//1、先找到链表中间节点,p,q两个指针p每次走一步,q每次走两步,当q到达尾部时p到达中间结点
//2、将L的后半段原地逆置
//3、从单链表前后两段各取一个结点重排
LNode *p=L->next,*q=L->next;
while(q->next!=NULL)
{
p=p->next;
q=q->next;
if(q->next!=NULL)q=q->next;//q每次走两步
}
q=p->next;
p->next=NULL;
LNode *r;//暂存q后面的结点
while(q!=NULL)
{
r=q->next;
q->next=p->next; //头插法逆置
p->next=q;
q=r;
}
LNode *s;
s=L->next;
q=p->next;
p->next=NULL; //p最后为尾结点,所以指针置空
while(q!=NULL)
{
r=q->next;
q->next=s->next;
s->next=q;
s=q->next; //s移动到下一个结点
q=r;
}
return L;
}
int main()
{
LinkList L;//使用头插法 这里的L1就是一个头指针
printf("请输入链表元素,输入9999表示结束\n");
L=List_TailInsert(L); // 1 2 3 4
PrintList(L);
printf("转换链表\n");
L=Change_List(L);
PrintList(L);
return 0;
}