链表——单链表
#include<stdlib.h>
#include<stdio.h>
#define Elemtype int
typedef struct LNode{
Elemtype data;
struct LNode *next;
}LNode,*LinkList;
void InitLink(LinkList &L)
{
L= (LNode*)malloc(sizeof (LNode));
L->next=NULL;
}
bool Empty(LinkList L)
{
if(L->next==NULL)
return true;
else
return false;
}
LNode * GetElem(LinkList L,int i)
{
int j=0;
LNode *p=L;
while(p!=NULL && j<i)
{
p=p->next;
j++;
}
return p;
}
void InsertLink(LinkList &L,int i,Elemtype e)
{
LNode *q= (LNode*)malloc(sizeof(LNode));
q->data=e;
LNode *p = GetElem(L,i-1);
q->next=p->next;
p->next=q;
}
void DeleteLink(LinkList &L,int i)
{
LNode *p= GetElem(L,i-1);
LNode *q=p->next;
p->next=q->next;
free(q);
}
void Length(LinkList L,int &s)
{
int i=0;
LNode *p=L;
while(p!=NULL)
{
p=p->next;
i++;
}
s=i-1;
}
void PrintLink(LinkList L)
{
LNode *p=L->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
以上是单链表的基操代码实现
以下是针对《2022年数据结构考研复习指导》课后复习题的训练内容
//习题2.1---递归删除无头结点所有x值结点
void DeleteCommon1(LinkList &L,Elemtype e)
{
LNode *p;
if(L==NULL)
return;
if(L->data==e)
{
p=L;
L=L->next;
free(p);
DeleteCommon1(L,e);
}
else
DeleteCommon1(L->next,e);
}
//习题2.2(1)---前结点删除所有x值
void DeleteCommon2(LinkList &L,Elemtype e)
{
LNode *p=L->next,*pre=L,*q;
while(p!=NULL)
{
if(p->data==e)
{
q=p;
p=p->next;
pre->next=p;
free(q);
}
else{
pre=p;
p=p->next;
}
}
}
//习题2.2(2)---尾结点删除所有x值
void DeleteCommon3(LinkList &L,Elemtype e)
{
LNode *p=L->next,*r=L,*q;
while(p!=NULL)
{
if(p->data!=e)
{
r->next=p;
r=p;
p=p->next;
}
if(p->data==e)
{
q=p;
p=p->next;
free(q);
}
}
r->next=NULL;
}
//习题2.3---递归法逆置输出
void ReversePrint(LinkList L)
{
if(L!=NULL){
ReversePrint(L->next);
printf("%d ",L->data);
}
if(L==NULL){
return;
}
}
//习题2.4---删除最小值
void DeleteMin(LinkList &L)
{
LNode *p=L->next,*pre=L,*q;
int t=p->data;
while(p!=NULL)
{
if(t>p->data)
{
q=pre;
t=p->data;
}
pre=p;
p=p->next;
}
LNode *k=q->next;
q->next=k->next;
free(k);
}
//习题2.5(1)---头插法逆置
void Reverse1(LinkList &L)
{
LNode *p=L->next->next,*r=L->next,*q;
while(p!=NULL)
{
q=p->next;
p->next=L->next;
L->next=p;
p=q;
}
r->next=NULL;
}
//习题2.5(2)---逆置箭头逆置
void Reverse2(LinkList &L)
{
LNode *pre,*p=L->next,*t=p->next;
p->next=NULL;
while(t!=NULL)
{
pre=p;
p=t;
t=t->next;
p->next=pre;
}
L->next=p;
}
//习题2.6---递增有序
void Sort(LinkList &L)
{
LNode *pre,*p=L->next,*r=p->next;
p->next=NULL;
p=r;
while(p!=NULL)
{
pre=L;
r=p->next;
while(pre->next!=NULL && pre->next->data<p->data)
{
pre=pre->next;
}
p->next=pre->next;
pre->next=p;
p=r;
}
}
//习题2.7---删除一个阈值内的值
void DeleteMid(LinkList &L,Elemtype s,Elemtype t)
{
LNode *pre=L,*p=L->next,*q;
while(p!=NULL)
{
if(p->data>=s && p->data<=t)
{
q=p;
p=p->next;
pre->next=p;
free(q);
}
else{
p=p->next;
pre=pre->next;
}
}
}
//习题2.8---寻找公共结点
LNode * SearchNode(LinkList L1,LinkList L2)
{
LinkList shortList,longList;
int i,j,dist;
Length(L1,i);
Length(L2,j);
if(i>=j)
{
shortList=L2;
longList=L1;
dist=i-j;
}
else{
shortList=L1;
longList=L2;
dist=j-i;
}
while(dist)
longList=longList->next;
while(longList!=NULL)
{
if(longList==shortList)
return longList;
else{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;
}
//习题2.9---递增输出
void PrintMin(LinkList &L)
{
while(L->next!=NULL)
{
int t=L->next->data;
LNode *pre=L,*p=L->next,*q;
while(p!=NULL)
{
if(p->data<=t)
{
t=p->data;
q=pre;
}
pre=pre->next;
p=p->next;
}
printf("%d ",q->next->data);
LNode *k=q->next;
q->next=k->next;
free(k);
}
free(L);
}
//习题2.10---分解为奇偶两个链表
void Decompose(LinkList &A,LinkList &B)
{
LNode *a=A,*b=B,*p=A->next;
while(p!=NULL)
{
if(p->data%2==0)
{
b->next=p;
b=b->next;
}
if(p->data%2==1)
{
a->next=p;
a=a->next;
}
p=p->next;
}
a->next=NULL;
b->next=NULL;
}
//习题2.11---分解为两个链表,并顺序和倒置
void Decompose_X(LinkList C,LinkList &A,LinkList &B)
{
int i=1;
LNode *a=A,*b=B,*p=C->next,*r;
b->next=NULL;
while(p!=NULL)
{
r=p->next;
if(i%2==0)
{
p->next=b->next;
b->next=p;
}
if(i%2==1)
{
a->next=p;
a=a->next;
}
p=r;
i++;
}
a->next=NULL;
}
//习题2.12---删除有序表的重复值
void DeleteRepeat(LinkList &L)
{
LNode *pre=L->next,*p=pre->next,*q;
while(p!=NULL)
{
if(pre->data==p->data)
{
q=p;
p=p->next;
pre->next=p;
free(q);
}
pre=pre->next;
p=p->next;
}
}
//习题2.13---合并两个递增链表为一个递减链表
void Combine(LinkList &A,LinkList &B)
{
LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
A->next=NULL;
while(ra!=NULL && rb!=NULL)
{
if(a->data <= b->data)
{
ra=a->next;
a->next=A->next;
A->next=a;
a=ra;
}
if(b->data <= a->data)
{
rb=b->next;
b->next=A->next;
A->next=b;
b=rb;
}
}
while(ra!=NULL)
{
ra=a->next;
a->next=A->next;
A->next=a;
a=ra;
}
while(rb!=NULL)
{
rb=b->next;
b->next=A->next;
A->next=b;
b=rb;
}
free(B);
}
//习题2.14---提取两个递增链表的公共元素,形成新链表
void ExtractCommon(LinkList &C,LinkList A,LinkList B)
{
LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
while(ra!=NULL && rb!=NULL)
{
if(a->data < b->data)
{
a=a->next;
ra=a->next;
}
if(a->data > b->data)
{
b=b->next;
rb=b->next;
}
if(a->data == b->data)
{
ra=a->next;
rb=b->next;
LNode *p=(LNode *) malloc(sizeof (LNode));
p->data=a->data;
p->next=C->next;
C->next=p;
a=ra;
b=rb;
}
}
}
//习题2.15---取交集,并存与原链表
void Intersection(LinkList &A,LinkList &B)
{
LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
A->next=NULL;
while(ra!=NULL && rb!=NULL)
{
if(a->data < b->data)
{
a=a->next;
ra=a->next;
}
if(a->data > b->data)
{
b=b->next;
rb=b->next;
}
if(a->data == b->data)
{
ra=a->next;
rb=b->next;
a->next=A->next;
A->next=a;
a=ra;
b=rb;
}
}
}
//习题2.16---判断是否是子序列
void JudgeSubsequence(LinkList &A,LinkList &B)
{
LNode *a=A,*q=a,*b=B;
while(b && a)
{
if(a->data == b->data)
{
a=a->next;
b=b->next;
}
else{
q=q->next;
a=q;
b=B;
}
}
if(b==NULL)
printf("B是A的子序列");
else
printf("B不是A的子序列");
}
//习题2.21---查找倒数第k值
void FindKey(LinkList &L,int k)
{
LNode *p=L->next,*q=L->next;
for(int i=k;i>0;i--)
{
p=p->next;
if(p==NULL)
printf("k值输入错误");
}
while(p!=NULL)
{
q=q->next;
p=p->next;
}
printf("倒数%d的值为%d",k,q->data);
}
//习题2.22---参考习题2.8
//习题2.23---删除绝对值相同的值
void DeleteABS(LinkList &L,int n)
{
LNode *pre=L,*p=pre->next;
int s[n];
for(int i=0;i<n+1;i++)
{
s[i]=0;
}
while(p!=NULL)
{
if(s[abs(p->data)]==0)
{
s[abs(p->data)]=1;
pre=p;
p=p->next;
}
if(s[abs(p->data)]==1)
{
LNode *q=p;
p=p->next;
pre->next=p;
free(q);
}
}
free(s);
}
//习题2.24---寻找环入口
LNode * JudgeCircle(LinkList &L)
{
LNode * fast=L,* slow=L;
while(slow!=NULL && fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
break;
}
LNode *p1=L,*p2=slow;
while(p1!=p2){
p1=p1->next;
p2=p2->next;
}
return p1;
}
//习题2.25---将后半链表逆置并插入
void ReSort(LinkList &L)
{
LNode *p1=L,*p2=L,*r,*p;
while(p2!=NULL)
{
p1=p1->next;
p2=p2->next;
if(p2!=NULL)
p2=p2->next;
}
p2=p1->next;
p1->next=NULL;
while(p2!=NULL)
{
r=p2->next;
p2->next=p1->next;
p1->next=p2;
p2=r;
}
p=L->next;
p2=p1->next;
p1->next=NULL;
while(p2!=NULL)
{
r=p2->next;
p2->next=p->next;
p->next=p2;
p=p2->next;
p2=r;
}
}