1.
void Delete(LNode *&L,int x)
{
LNode *p; //p指向待删除结点
if(L == NULL) //递归出口
return;
if(L->data == x) //若L所指结点的值为x
{
p = L;
L = L->next;
free(p);
Delete(L,x); //递归调用
}
else //若L所指结点的值不为x
{
Delete(L->next,x); //递归调用
}
}
2.
//要删除一个结点必须知道其前驱结点
void Delete(LNode *&L,int x)
{
LNode *p = L->next;
LNode *pre = L;
LNode *q;
while(p != NULL)
{
if(p->data == x)
{
q = p; //q
p = p->next;
pre ->next = p;
free(q);
}
else
{
pre = p;
p = p->next;
}
}
}
void Delete(LNode *&L,int x)
{
LNode *p = L-next; //p为工作指针,用来扫描整个链表,指向开始结点
LNode *r = L; //r指向尾结点,其初值为头结点
LNode *q;
while(p != NULL)
{
if(p->data != x) //p结点不为x时将其链接到L尾部
{
r->next = p;
r = p; //r始终指向尾结点
p = p-next; //继续扫描
}
else
{
q = p; //接收要被删除的结点
p = p->next; //继续扫描
free(q);
}
}
r-next = NULL;
}
3.
void RePrint(LNode *L)
{
if(L-next != NULL)
{
RePrint(L->next); //递归
}
print(L->data); //输出函数
}
4.
void DeleteMin(LNode *&L)
{
LNode *p = L->next;
LNode *pre = L;
LNode *minp = p;
LNode *preminp = pre;
while(p != NULL)
{
if(p->data < minp->data)
{
minp = p;
preminp = pre;
}
pre = p;
p = p->next;
}
preminp->next = minp->next;
free(minp);
}
5.
void Reverse(LNode *L)
{
LNode *p = L->next; //p为工作指针,用来扫描整个链表
LNode *r; //r为p的后继,以防断链
L->next = NULL; //将头结点L的next域置为NULL
while(p != NULL) //头插法建立链表
{
r = p->next; //暂存p结点的后继
p->next = L->next;
L-next = p;
p = r;
}
}
void Reverse(LNode *L)
{
LNode *pre;
LNode *p = L->next;
LNode *r = p->next;
p->next = NULL; //处理第一个结点
while(r != NULL) //r为空则说明p为最后一个结点
{
pre = p; //依次继续遍历
p = r;
r = r->next;
p->next = pre; //指针反转
}
L->next = p; //处理最后一个结点
}
6.
void Sort(LNode *&L)
{ //本算法实现将单链表L的结点重排,使其递增有序
LNode *p = L->next;
LNode *pre;
LNode *r = p->next; //r保持*p后继结点指针,以保证不断链
p->next = NULL; //构造只含一个数据结点的有序表
p = r;
while(p != NULL)
{
r = p->next; //保存*p的后继结点指针
pre = L;
while(pre->next != NULL && pre-next->data < p->data) //直到pre->next为NULL||pre->data >= p->data时循环结束
pre = pre->next;
p->next = pre->next; //找到比当前pre->next结点小的结点,插在pre结点之后
pre->next = p;
p = r;
}
}
7.
void DeleteNode(LNode *&L,int min,int max)
{
LNode *p; //工作指针,扫描一遍链表
LNode *pre;
p = L-next;
pre = L;
while(p != NULL)
{
if(p->data > min || p->data < max)
{
pre ->next = p->next;
free(p);
p = pre->next;
}
else
{
pre = p;
p = p->next;
}
}
}
8.
LNode *SearchCommon(LNode *L1,LNode *L2)
{//本算法实现在线性的时间内找到两个单链表的第一个公共结点
int length1 = Length(L1);
int length2 = Length(L2); //计算两个链表的长度
LNode *longList,*shortList;
if(length1 < length2)
{
longList = L1->next;
shortList = L2->next;
dist = length1 - length2; //表长之差
}
else
{
longList = L2->next;
shortList = L1->next;
dist = length2 - length1;
}
while(dist--) //表长的链表先遍历到第dist个结点
{
longList = longList->next;
}
while(longList != NULL)
{
if(longList == shortList)
return longList;
else
{
longList = longList->next;
shortList = shortList->next;
}
}
return NULL;
}
9.
void DeleteMin(LNode *head)
{//head是带头结点的单链表的头指针,本算法按递增顺序输出单链表中的数据元素
LNode *pre,*p,*u;
while(head->next != NULL)
{
pre = head;
p = pre->next; //p为工作指针
while(p->next != NULL)
{
if(p->next->data < pre->next->data)
{
pre = p;
p = p->next;
}
}
print(pre->next->data);
u = pre->next;
pre->next = u->next;
free(u);
}
free(head); //释放头结点
}
10.
void Split(LNode *A,LNode *&B)
{
LNode *p,*q,*r;
B = (LNode*)malloc(sizeof(LNode));
B->next = NULL;
r = B;
p = A;
while(p->next != NULL) //p始终指向当前被判断结点的前驱结点
{
if(p->next->data%2 == 0) //判断结点是否为偶数,是偶数则从链表中取下来
{
q = p->next;
p->next = q->next;
q->next = NULL;
r->next = q;
r = q;
}
else
{
p = p->next; //p后移一个位置,即开始检查下一个结点
}
}
}
11.
void CreateLink(LNode *&A)
{
LNode *B =(LNode*)malloc(sizeof(LNode));
B->next = NULL;
LNode *p = A->next;
LNode *q;
LNode *ra = A; //ra始终指向A的尾结点
while(p != NULL)
{
ra->next = p;
ra = p; //将*p链到A的表尾
p = p->next;
q = p->next; //头插后,*p将断链,因此用q记忆*p的后继
p->next = B->next; //将*p插入到B的前端
B->next = p;
p = q;
}
ra->next = NULL;
}
12.
void Delete(LNode *&L)
{
LNode *p = L->next; //p为扫描工作指针
LNode *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;
}
}
void Delete(LNode *&L)
{
LNode *p = L->next;
LNode *q = L->next-next;
LNode *r;
while(q != NULL)
{
while(q != NULL && q->data == p->data)
q = q->next;
if(q != NULL)
{
p = p->next;
p->data = q->data;
}
}
q = p->next;
p->next = NULL;
while(q != NULL) //释放p之后的所有结点
{
r = q;
q = q->next;
free(r);
}
}
13.
void merge(LNode *A,LNode *B,LNode *&C)
{ //合并两个递增有序链表(带头结点),并使合并后的链表递减排列
LNode *p = A->next;
LNode *q = B->next;
LNode *s;
C = A;
C->next = NULL;
free(B);
while(p != NULL && q != NULL)
{
if(p->data <= q->data)
{
s = p; //s保存p结点指针用来头插法操作使用
p = p->next;
s->next = C->next;
C->next = s;
}
else
{
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
}
while(p != NULL)
{
s = p;
p = p->next;
s->next = C->next;
C->next = s;
}
while(q != NULL)
{
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
}
14.
void GetCommon(LNode *A,LNode *B)
{
LNode *p = A->next;
LNode *q = B->next;
LNode *r,*s;
LNode *C = (LNode *)malloc(sizeof(LNode)); //建立表C
r = C;
while(p != NULL && q != NULL)
{
if(p->data < q->data) //若A的当前元素较小,后移指针
p = p->next;
else if(p->data > q->data) //若B的当前元素较小,后移指针
q = q->next;
else
{
s = (LNode*)malloc(sizeof(LNode));
s->data = p->data;
r->next = s; //尾插法
r = s;
p = p->next;
q = q->next;
}
}
r->next = NULL; //置C尾结点指针为空
}
15.
void Merge(LNode *&A,LNode *&B)
{
LNode *pa = A->next;
LNode *pb = B->next;
LNode *pc = A;
LNode *u;
while(pa != NULL && pb != NULL)
{
if(pa->data == pb->data) //交集并入结果表中
{
pc->next = pa;
pc = pa;
pa = pa->next;
u = pb;
pb = pb->next;
free(u);
}
else if(pa->data < pb->data) //若A中当前结点值小于B中当前结点值
{
u = pa;
pa = pa->next;
free(u);
}
else
{
u = pb;
pb = pb->next;
free(u);
}
}
while(pa != NULL) //B已遍历完,A未完
{
u = pa;
pa = pa->next;
free(u);
}
while(pb != NULL) //A已遍历完,B未完
{
u = pb;
pb = pb->next;
free(u);
}
pc->next = NULL; //置结果链表尾指针为NULL;
free(B); //释放B表头结点
}
16.
bool isSubLink(LNode *A,LNode *B)
{
LNode *p = A->next;
LNode *q = B->next;
LNode *pre = p; //pre记住每趟比较中A链表的开始结点
while(p != NULL && q != NULL)
{
if(p->data != q->data) //结点值不同
{
pre = pre->next;
p = pre; //A链表新的开始比较结点
q = B->next; //q从B链表第一个结点开始
}
if(p->data == q->data) //结点值相同
{
p = p->next;
q = q->next;
}
}
if(q == NULL)
return true;
else
return false;
}
17.
int Symmetry(DLNode *L)
{ //本算法是从两头扫描循环双链表,以判断链表是否对称
DLNode *p = L->next;
DLNode *q = L->prior;
while(p != q && p->next != q)
{
if(p->data == q->data)
{
p = p->next;
q = q->prior;
}
else
return 0;
}
return 1;
}
18.
设置指针p遍历h1直到找到尾结点,也就是next为h1,将其链接到h2,
p继续遍历直到找到h2尾指针,也就是next为h2,修改指向h1
void GetNewLink(LNode *&h1,LNode *&h2)
{
LNode *p = h1;
while(p->next != h1)
{
p = p->next; //此时p为h1尾结点
}
p->next = h2;
p = p->next;
while(p->next != h2)
{
p = p->next; //此时p为h2尾结点
}
p->next = h1;
}
19.
void Delete(LNode *&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;
}
pre = p;
p = p->next;
}
printf("%d",minp->data); //输出最小值结点元素
minpre->next = minp->next; //最小值结点从表中"断开"
free(minp);
}
free(L); //释放头结点
}
20.
DLNode *Locate(DLNode *&L,int x)
{//本算法先查找数据x,查找成功时结点的访问频度域+1
//最后将该结点按频度递减插入链表中适当的位置(同频度最近访问的在前面)
DLNode *p = L->next,*q; //p为工作指针,q为p的前驱,用于查找插入位置
while(p != NULL && p->data != x)
p = p->next;
if(p == NULL)
printf("不存在值为x的结点\n");
return NULL;
else
{
p->freq++; //令元素值为x的结点的freq域+1
p->next->pred = p->pred;
p->pred->next = p->next; //将p结点从链表上摘下
q = p->pred;
while(q != L && q->freq <= p->freq)
q = q->pred;
p->next = q->next;
p->pred = q;
q->next->pred = p;
q->next = p;
}
return p;
}
21.
typedef int ElemType; //链表数据的类型定义
typedef struct LNode
{
ElemType data;
struct LNode *link;
}LNode;
int Search(LNode *list,int k)
{
LNode *p = list->link;
LNode *q = list->link; //指针p,q指示第一个结点
int count = 0;
while(p != NULL) //遍历链表直到最后一个结点
{
if(count < k) //计数,若count<k只移动p
count++;
else
q = q->list; //之后让p,q同步移动
p = p->link;
}
if(count < k)
return 0;
else
{
printf("%d",q->data);
return 1;
}
}
22.
typedef struct Node
{
char data;
struct Node *next;
}Node;
//求链表长度的函数
int listLength(Node *head)
{
int len = 0;
while(head->next != NULL)
{
len++;
head = head->next;
}
return len;
}
//找到共同后缀的起始地址
Node *findCommon(Node *str1,Node *str2)
{
int m,n;
Node *p,*q;
m = listLength(str1); //求str1的长度
n = listLength(str2); //求str2的长度
for(p=str1;m>n;m--) //若m>n,使p指向链表中的第m-n+1个结点
p = p->next;
for(q=str2;m<n;n--) //若m<n,使q指向链表中的第n-m+1个结点
q = q->next;
while(p->next != NULL && q->next != NULL && p->next != q->next)
{ //将指针p和q同步向后移动
p = p->next;
q = q->next;
}
return p->next;
}
23.
typedef struct LNode
{
int data;
struct LNode *link;
}LNode;
void findAndDelete(LNode *head,int n)
{
LNode *p =head;
LNode *r;
int *q;
int m;
q = (int *)malloc(sizeof(int)*(n+1)); //申请n+1个位置的辅助空间
for(int i=0;i<n+1;i++)
{
*(q+i) = 0; //为辅助数组赋值为0
}
while(p->link != NULL)
{
m = p->link->data>0? p->link->data:-(p->link->data);
if(*(q+m) == 0) //判断该结点的data是否已经出现
{
*(q+m) == 1; //首次出现
p = p->link; //保留
}
else //重复出现
{
r = p->link;
p->link = r->link; //删除
free(r);
}
}
free(q);
} //时间复杂度为O(m),空间复杂度为O(n);