目录
1.设计一个递归算法,删除不带头结点的单链表L中所有制为x的结点。编辑
2.在带头结点的单链表L中,删除所有值为x的结点,并释放其空间。假设值为x的结点不唯一,试编写算法以实现上述操作。
3.设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。编辑
4.试编写在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值结点是唯一的)。编辑
5.试编写算法将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1)。编辑
6.有一个带头结点的单链表L,设计一个算法使其元素递增有序。编辑
7.设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素(若存在)。
10.将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。编辑
13.假设有两个按元素值递增次序排列的线性表,均以单链表形式存储,请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。编辑
14.设A和B是两个单链表(带头结点),其中元素递增有序。设计一个算法从A和B中公共元素产生单链表C,要求不破坏A、B的结点。编辑
15.已知两个链表A和B分别表示两个集合,其元素递增排列。编制函数,求A和B的交集,并存放于A链表中。编辑
16.两个整数序列A=a1,a2,a3,...,am和B=b1,b2,...,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的连续子序列。编辑
17. 设计一个算法用于判断带头结点的循环双链表是否对称。编辑
18.有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。编辑
19.设有一个带头结点的循环单链表,其结点值均为正整数。设计一个算法,反复找出单链表中结点值最小的结点并输出。然后将该结点从中删除,直到单链表空为止,再删除表头结点。编辑
24. 设线性表采用带头结点的单链表保存,请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L的各结点,得到线性表L'=(a1,an,a2,an-1,a3,an-2,...)。编辑
1.设计一个递归算法,删除不带头结点的单链表L中所有制为x的结点。
/*
设计一个递归算法,
删除不带头结点的单链表L中所有制为x的结点。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data;
struct LNode* Next;
}LNode;
int a[4] = { 1,2,3,4 };
int n = 4;
void buildList(LNode* L)
{
LNode* s, * r = L;
r->data = a[0];
if (n == 1)
r->Next = NULL;
else
{
for (int i = 1; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a[i];
s->Next = NULL;
r->Next = s;
r = r->Next;
}
}
}
void display(LNode* L)
{
LNode* s = L;
while (s!=NULL)
{
printf("%3d", s->data);
s = s->Next;
}
printf("\n");
}
void deleteNum(LNode*& L, int x)
{
if (L == NULL)
return;
LNode* p;
if (L->data == x)
{
p = L;
L = L->Next;
free(p);
deleteNum(L, x);
}
else
deleteNum(L->Next, x);
}
int main()
{
LNode List;
LNode* L = &List;
buildList(L);
display(L);
deleteNum(L, 2);
display(L);
return 0;
}
2.在带头结点的单链表L中,删除所有值为x的结点,并释放其空间。假设值为x的结点不唯一,试编写算法以实现上述操作。
/*
在带头结点的单链表L中,删除所有值为x的结点,并释放其空间。
假设值为x的结点不唯一,试编写算法以实现上述操作。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data;
struct LNode* next;
}LNode,*linkList;
int a[4] = { 1,3,6,6 };
int n = 4;
void TailInsert(linkList& L)
{
L = (linkList)malloc(sizeof(LNode));
LNode* s,*r=L;
for (int i = 0; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a[i];
s->next = NULL;
r->next = s;
r = r->next;
}
}
void display(linkList L)
{
LNode* s = L->next;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
void deleteNum(linkList& L, int x)
{
LNode* p = L->next, * q, * r = L;
while (p)
{
if (p->data != x)
{
r->next = p;
r = p;
p = p->next;
}
else
{
q = p;
p = p->next;
free(q);
r->next = p;
}
}
}
int main()
{
linkList L;
TailInsert(L);
display(L);
deleteNum(L, 3);
display(L);
return 0;
}
3.设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。
/*
设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data;
struct LNode* next;
}LNode;
int a[4] = { 1,2,3,4 };
int n = 4;
void buildList(LNode *L)
{
LNode* r = L, * s;
r->data = a[0];
if (n == 1)
r->next = NULL;
else
{
for (int i = 1; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
}
void display(LNode* L)
{
if (L != NULL)
{
display(L->next);
printf("%3d", L->data);
}
else
return;
}
int main()
{
LNode Head;
LNode* L = &Head;
buildList(L);
display(L);
return 0;
}
4.试编写在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值结点是唯一的)。
/*
试编写在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值结点是唯一的)
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, * linklist;
int a[4] = { 23,12,5,34 };
int n = 4;
void buildList(linklist& L)
{
L = (linklist)malloc(sizeof(lnode));
lnode* r = L, * s;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
void display(linklist L)
{
lnode* s = L->next;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
void deleteMin(linklist& L)
{
//s是要删除结点的前驱结点
lnode* p = L->next, * q, * r = L, * s;
q = p;
s = r;
while (p)
{
if (p->data < q->data)
{
q = p;
s = r;
}
r = p;
p = p->next;
}
s->next = q->next;
free(q);
}
int main()
{
linklist L;
buildList(L);
display(L);
deleteMin(L);
display(L);
return 0;
}
5.试编写算法将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1)。
/*
试编写算法将带头结点的单链表就地逆置,
所谓“就地”是指辅助空间复杂度为O(1)
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, *linklist;
int a[4] = { 1,2,3,4 };
int n = 4;
void bulidList(linklist& L)
{
L = (linklist)malloc(sizeof(lnode));
lnode* r = L, * s;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
void display(linklist L)
{
lnode* s = L->next;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
void reverseList(linklist& L)
{
lnode* p = L->next, * r;
L->next = NULL;
while (p)
{
r = p->next;
p->next = L->next;
L->next = p;
p = r;
}
}
int main()
{
linklist L;
bulidList(L);
printf("逆置之前:\n");
display(L);
printf("逆置之后:\n");
reverseList(L);
display(L);
return 0;
}
6.有一个带头结点的单链表L,设计一个算法使其元素递增有序。
/*
有一个带头结点的单链表L,
设计一个算法使其元素递增有序
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, *linklist;
int a[4] = { 3,7,1,5 };
int n = 4;
void buildList(linklist& L)
{
L = (linklist)malloc(sizeof(lnode));
lnode* r = L, * s;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
void display(linklist L)
{
lnode* s = L->next;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
void sortList(linklist& L)
{
lnode* p = L->next, * r = p->next, * f;
p->next = NULL;
p = r;
while (p)
{
r = p->next;
f = L;
while (f->next != NULL && f->next->data < p->data)
f = f->next;
p->next = f->next;
f->next = p;
p = r;
}
}
int main()
{
linklist L;
buildList(L);
printf("递增排序之前:\n");
display(L);
sortList(L);
printf("递增排序之后:\n");
display(L);
return 0;
}
7.设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素(若存在)。
/*
设在一个带表头结点的单链表中所有元素结点的数据值无序,
试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素(若存在)。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, * linklist;
int a[5] = { 1,5,3,4,2 };
int n = 5;
void buildList(linklist& L)
{
L = (linklist)malloc(sizeof(lnode));
lnode* s, * r = L;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
void display(linklist L)
{
lnode* s = L->next;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
void deleteNum(linklist& L, int left, int right)
{
lnode* p = L->next, * r = L;
while (p)
{
if (p->data > left && p->data < right)
{
r->next = p->next;
free(p);
p = r->next;
}
else
{
r = p;
p = p->next;
}
}
}
int main()
{
linklist L;
buildList(L);
printf("删除之前:\n");
display(L);
deleteNum(L, 2, 5);
printf("删除之后:\n");
display(L);
return 0;
}
8.给定两个单链表,编写算法找出两个链表的公共结点。
/*
给定两个单链表,编写算法找出两个链表的公共结点。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, * linklist;
int a[5] = { 2,4,3,7,8 };
int b[4] = { 1,3,7,8 };
int n1 = 5, n2 = 4;
void buildList(linklist& L,int aa[],int n)
{
L = (linklist)malloc(sizeof(lnode));
L->data = 0;
lnode* s, * r = L;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = aa[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
int lengthList(linklist L)
{
int len = 0;
lnode* s = L->next;
while (s)
{
len++;
s = s->next;
}
return len;
}
linklist commonNode(linklist L1, linklist L2)
{
int len1 = lengthList(L1);
int len2 = lengthList(L2);
int dist = 0;
linklist Long, Short;
if (len1 > len2)
{
Long = L1->next;
Short = L2->next;
dist = len1 - len2;
}
else
{
Long = L2->next;
Short = L1->next;
dist = len2 - len1;
}
/*
while(dist--) Long=Long->next;
*/
while (dist)
{
Long = Long->next;
dist--;
}
while (Long)
{
if (Short->data == Long->data&&\
Long->next->data==Short->next->data)
return Short;
else
{
Short = Short->next;
Long = Long->next;
}
}
return NULL;
}
linklist commonNode1(linklist L1, linklist L2)
{
lnode* s1 = L1->next;
while (s1)
{
lnode* s2 = L2->next;
while (s2)
{
if (s1->data == s2->data && \
s1->next->data == s2->next->data)
return s1;
else
s2 = s2->next;
}
s1 = s1->next;
}
return NULL;
}
void display(linklist L)
{
lnode* s;
if (L->data == 0)
s = L->next;
else
s = L;
while (s)
{
printf("%3d", s->data);
s = s->next;
}
printf("\n");
}
int main()
{
linklist L1, L2;
buildList(L1, a, n1);
buildList(L2, b, n2);
printf("L1:");
display(L1);
printf("L2:");
display(L2);
//两个commonNode都可以实现复杂度不同
linklist L3 = commonNode1(L1, L2);
printf("共同结点是:%3d\n", L3->data);
printf("L3:");
display(L3);
return 0;
}
9.给定一个带表头结点的单链表,设head为头指针,结点的结构为(data,next),data为整型元素,next为指针,试写出算法;按递增次序输出单链表中各结点的数据元素,并释放结点所占存储空间(要求:不允许使用数组作为辅助空间)。
/*
给定一个带表头结点的单链表,
按递增次序输出单链表中各结点的数据元素,
并释放结点所占存储空间(要求:不允许使用数组作为辅助空间)
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct lnode {
int data;
struct lnode* next;
}lnode, * linklist;
int a[5] = { 2,5,3,8,1 };
int n = 5;
void buildList(linklist& L)
{
L = (linklist)malloc(sizeof(lnode));
lnode* s, * r = L;
for (int i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
void dele