完整试题以及代码可以在我的小程序上搜索查看。
1、 编写算法,将二个升序链表在原表空间内归并成一个升序链表。
/* 1、 编写算法,将二个升序链表在原表空间内归并成一个升序链表。*/
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElementType;
typedef struct LNode {
ElementType data;
struct LNode *Next;
} LNode,*List;
/*尾插法建立链表L */
void createListR(LNode *&L) {
LNode *s, *r; //s用来指向新申请的结点,r始终指向L的终端结点
ElementType x;
L = (LNode *)malloc(sizeof(struct LNode));//申请L的头结点空间
L->Next = NULL;
r = L;//r指向头结点,因为此时头结点就是终端结点
printf("\n(尾插法)请依次输入链表元素(以-999作结束标志):\n");
while(1) {
//循环申请结点来接收输入缓冲区中的元素,直到遇到-999结束接收
scanf("%d",&x);
if(x == -999) break;
s = (LNode *)malloc(sizeof(struct LNode));//s指向新申请的结点
s->data = x;//用新申请的结点来接收输入的元素
r->Next = s;//用r来接纳新结点
r = r->Next;//r指向终端结点,以便于接纳下一个到来的结点
}
r->Next = NULL;//输入缓冲区的所有元素都已经装入链表L中,L的终端结点的指针域置位NULL,L建立完成
}
/*打印链表*/
void printList(LNode *L) {
LNode *p = L->Next;
// printf("\n链表元素依次为:");
while(p != NULL) {
printf("%d ",p->data);
p = p->Next;
}
printf("\n");
}
//以下是题目算法
void merge_up(LNode *&A, LNode *B) {
LNode *p = A->Next;
LNode *q = B->Next;
LNode *s;
A->Next = NULL;
free(B);
s = A;
while(p !=NULL && q != NULL) {
if(p->data <= q->data) {
s->Next = p;
p = p->Next;
s = s->Next;
} else {
s->Next = q;
q = q->Next;
s = s->Next;
}
}
s->Next = NULL;
//以下两个if语句将还有剩余结点的链表链接在A的尾部
if(p != NULL) s->Next = p;
if(q != NULL) s->Next = q;
}
int main(){
LNode *La,*Lb;
printf("1、编写算法,将二个升序链表在原表空间内归并成一个升序链表。\n");
printf("尾插法创建链表La(元素升序):");
createListR(*&La);
printf("尾插法创建链表Lb(元素升序):");
createListR(*&Lb);
merge_up(La, Lb);
printf("归并成一个升序链表(仍使用原表的存储空间):");
printList(La);
system("pause");
return 0;
}
2、 编写算法,将二个升序链表在原表空间内归并成一个降序链表。
/* 2、 编写算法,将二个升序链表在原表空间内归并成一个降序链表。*/
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElementType;
typedef struct LNode {
ElementType data;
struct LNode *Next;
} LNode,*List;
/*尾插法建立链表L */
void createListR(LNode *&L) {
LNode *s, *r; //s用来指向新申请的结点,r始终指向L的终端结点
ElementType x;
L = (LNode *)malloc(sizeof(struct LNode));//申请L的头结点空间
L->Next = NULL;
r = L;//r指向头结点,因为此时头结点就是终端结点
printf("\n(尾插法)请依次输入链表元素(以-999作结束标志):\n");
while(1) {
//循环申请结点来接收输入缓冲区中的元素,直到遇到-999结束接收
scanf("%d",&x);
if(x == -999) break;
s = (LNode *)malloc(sizeof(struct LNode));//s指向新申请的结点
s->data = x;//用新申请的结点来接收输入的元素
r->Next = s;//用r来接纳新结点
r = r->Next;//r指向终端结点,以便于接纳下一个到来的结点
}
r->Next = NULL;//输入缓冲区的所有元素都已经装入链表L中,L的终端结点的指针域置位NULL,L建立完成
}
/*打印链表*/
void printList(LNode *L) {
LNode *p = L->Next;
// printf("\n链表元素依次为:");
while(p != NULL) {
printf("%d ",p->data);
p = p->Next;
}
printf("\n");
}
//题目要求的算法
void merge_down(LNode *&A, LNode *B) {
LNode *p = A->Next;
LNode *q = B->Next;
LNode *s;
A->Next = NULL;
free(B);
while(p !=NULL && q != NULL) {
//下边的if else语句体现了链表的头插法
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;
}
}
//下边两个循环是和求递增归并序列不同的地方,必须将剩余元素逐个插入C的头部才能得到最终的递减序列
while(p != NULL) {
s = p;
p = p->Next;
s->Next = A->Next;
A->Next = s;
}
while(q != NULL) {
s = q;
q = q->Next;
s->Next = A->Next;
A->Next = s;
}
}
int main(){
LNode *La,*Lb;
printf("2、 编写算法,将二个升序链表在原表空间内归并成一个降序链表。\n");
printf("创建链表La(元素升序):");
createListR(*&La);
printf("创建链表Lb(元素升序):");
createListR(*&Lb);
merge_down(La, Lb);
printf("归并成一个降序链表(仍使用原来两个链表的存储空间):");
printList(La);
system("pause");
return 0;
}
3、 编写算法,用顺序存储结构实现二个升序集合的A=A-B运算。
/*3、 编写算法,用顺序存储结构实现二个升序集合的A=A-B运算。*/
#include<stdio.h>
#include <stdlib.h>
#define maxsize 10
typedef struct sqlist {
int data[maxsize];
int length;
} sqlist,*lnode;
void create(lnode &l,int a[],int n) {
l=(sqlist*)malloc(sizeof(sqlist));
for(int i=0; i<n; i++) {
l->data[i]=a[i];
}
l->length=n;
}
void del(lnode &l,int n) {
int i;
for(i=n; i<l->length-1; i++) {
l->data[i]=l->data[i+1];
}
l->length--;
}
void listminus(lnode &a,lnode b) {
int m=a->length,n=b->length;
int i,j,k=0;
for(i=0; i<m; i++) {
for(j=k; j<=n; j++) {
if(a->data[i]==b->data[j]) {
del(a,i);
k=j+1;
}
}
}
}
void show(lnode l) {
int i;
for(i=0; i<l->length; i++)
printf("%d ",l->data[i]);
}
int main() {
printf("3、 编写算法,用顺序存储结构实现二个升序集合的A=A-B运算。\n");
lnode A,B;
int a[10],b[10],i;
printf("input six number: ");
for(i=0; i<6; i++) {
scanf("%d",&a[i]);
}
printf("input six number: ");
for(i=0; i<6; i++) {
scanf("%d",&b[i]);
}
create(A,a,6);
create(B,b,6);
listminus(A,B);
printf("\nA = A-B :\n");
show(A);
printf("\n");
system("pause");
return 0;
}
4、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递增有序。
/*4、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递增有序。*/
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} LNode, * LinkList;
void CreateList(LNode* A) {
// 创建单循环链表,返回链表头
LNode* p;
int i, n;
printf("输入链表的元素个数:");
scanf("%d", &n);//输入集合元素的个数
printf("输入链表元素(按升序):");
for (i = 0; i < n; i++) {
p = (LNode*)malloc(sizeof(LNode));
scanf("%d", &p->data);//输入每个元素,空格隔开
p->next = A->next;
A->next = p;
A = p;
}
}
void PrintList(LNode* head) {
LNode* p = head->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
}
void listASC(LNode* A, LNode* B, LNode* C) {
//用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递增有序
LNode* pa, * pb, * pc;
int count;
pa = A->next;
pc = C->next;
while (pa) {
count = 0;
pb = B->next;
while (pb) {
if (pa->data == pb->data)
count++;
pb = pb->next;
}
if (count == 0) {
pc = (LNode*)malloc(sizeof(LNode));
pc->data = pa->data;
pc->next = C->next;
C->next = pc;
C = pc;
}
pa = pa->next;
}
}
void listDESC(LNode* A, LNode* B, LNode* C) {
//用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递减有序
LNode* pa, * pb, * pc, * p;
int count;
pa = A->next;
pc = C->next;
while (pa) {
count = 0;
pb = B->next;
while (pb) {
if (pa->data == pb->data)
count++;
pb = pb->next;
}
if (count == 0) {
pc = (LNode*)malloc(sizeof(LNode));
pc->data = pa->data;
pc->next = C->next;
C->next = pc;
}
pa = pa->next;
}
}
int main() {
printf("4、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递增有序。\n");
LNode* A, * B, * C;
A = (LNode*)malloc(sizeof(LNode));
A->next = NULL;
B = (LNode*)malloc(sizeof(LNode));
B->next = NULL;
C = (LNode*)malloc(sizeof(LNode));
C->next = NULL;
CreateList(A);
CreateList(B);
listASC(A, B, C);
printf("\nC = A-B :\n");
PrintList(C);
printf("\n");
system("pause");
return 0;
}
5、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递减有序。
/*5、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递减有序。*/
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} LNode, * LinkList;
void CreateList(LNode* A) {
// 创建单循环链表,返回链表头
LNode* p;
int i, n;
printf("输入链表的元素个数:");
scanf("%d", &n);//输入集合元素的个数
printf("输入链表元素(按升序):");
for (i = 0; i < n; i++) {
p = (LNode*)malloc(sizeof(LNode));
scanf("%d", &p->data);//输入每个元素,空格隔开
p->next = A->next;
A->next = p;
A = p;
}
}
void PrintList(LNode* head) {
LNode* p = head->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
}
void listASC(LNode* A, LNode* B, LNode* C) {
//用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递增有序
LNode* pa, * pb, * pc;
int count;
pa = A->next;
pc = C->next;
while (pa) {
count = 0;
pb = B->next;
while (pb) {
if (pa->data == pb->data)
count++;
pb = pb->next;
}
if (count == 0) {
pc = (LNode*)malloc(sizeof(LNode));
pc->data = pa->data;
pc->next = C->next;
C->next = pc;
C = pc;
}
pa = pa->next;
}
}
void listDESC(LNode* A, LNode* B, LNode* C) {
//用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递减有序
LNode* pa, * pb, * pc, * p;
int count;
pa = A->next;
pc = C->next;
while (pa) {
count = 0;
pb = B->next;
while (pb) {
if (pa->data == pb->data)
count++;
pb = pb->next;
}
if (count == 0) {
pc = (LNode*)malloc(sizeof(LNode));
pc->data = pa->data;
pc->next = C->next;
C->next = pc;
}
pa = pa->next;
}
}
int main() {
printf("5、 编写算法,用单链表实现二个升序集合A和B的差集存放在集合C,即C=A-B运算,要求C中元素递减有序。\n");
LNode* A, * B, * C;
A = (LNode*)malloc(sizeof(LNode));
A->next = NULL;
B = (LNode*)malloc(sizeof(LNode));
B->next = NULL;
C = (LNode*)malloc(sizeof(LNode));
C->next = NULL;
CreateList(A);
CreateList(B);
printf("\nC = A-B :\n");
listDESC(A, B, C);
PrintList(C);
printf("\n");
system("pause");
return 0;
}
6、 编写算法,将一单链表就地逆置。
/*6、 编写算法,将一单链表就地逆置。*/
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElementType;
typedef struct LNode {
ElementType data;
struct LNode *Next;
} LNode,*List;
/*尾插法建立链表L */
void createListR(LNode *&L) {
LNode *s, *r; //s用来指向新申请的结点,r始终指向L的终端结点
ElementType x;
L = (LNode *)malloc(sizeof(struct LNode));//申请L的头结点空间
L->Next = NULL;
r = L;//r指向头结点,因为此时头结点就是终端结点
printf("\n(尾插法)请依次输入链表元素(以-999作结束标志):\n");
while(1) {
//循环申请结点来接收输入缓冲区中的元素,直到遇到-999结束接收
scanf("%d",&x);
if(x == -999) break;
s = (LNode *)malloc(sizeof(struct LNode));//s指向新申请的结点
s->data = x;//用新申请的结点来接收输入的元素
r->Next = s;//用r来接纳新结点
r = r->Next;//r指向终端结点,以便于接纳下一个到来的结点
}
r->Next = NULL;//输入缓冲区的所有元素都已经装入链表L中,L的终端结点的指针域置位NULL,L建立完成
}
/*打印链表*/
void printList(LNode *L) {
LNode *p = L->Next;
// printf("\n链表元素依次为:");
while(p != NULL) {
printf("%d ",p->data);
p = p->Next;
}
printf("\n");
}
/*解法一:将头结点摘下,然后从第一结点开始,依次插入到头结点的后面(头插法建立单链
表),直到最后一个结点为止,这样就实现了链表的逆置
*/
LNode * Reverse_1 (LNode *L) {
//L是带头结点的单链表,本算法将L就地逆置
LNode *p, *r;//p为工作指针,r为p的后继,以防断链
p=L->Next;//从第一个元素结点开始
L->Next=NULL;//先将头结点L的Next域置为NULL
while (p!=NULL) {
//依次将元素结点摘下
r=p->Next;//暂存P的后继
p->Next=L->Next;//将P结点插入到头结点之后
L->Next=p;
p=r;
}
return L;
}
/*解法二 :假设pre、p和r指向3个相邻的结点,如下图所示。假设经过若干操作后,*pre 之前的;
结点的指针都已调整完毕,它们的Next都指向其原前驱结点。现在令*p结点的Next域指向
*pre结点,注意到一旦调整指针的指向后,*p 的后继结点的链就会断开,为此需要用r来指向
原*p的后继结点。处理时需要注意两点:一是在处理第一个结点时,应将其Next域置为NULL,
而不是指向头结点(因为它将作为新表的尾结点);二是在处理完最后一个结点后,需要将头结
点的指针指向它。
*/
LNode * Reverse_2 (LNode *L) {
//依次遍历线性表L,并将结点指针反转
LNode *pre, *p=L->Next, *r=p->Next;
p->Next=NULL;//处理第一个结点
while(r!=NULL) {
//r为空,则说明p为最后一个结点
pre=p;//依次继续遍历
p=r;
r=r->Next;
p->Next=pre;//指针反转
}
L->Next=p;//处理最后一个结点
return L;
}
int main(){
LNode *La;
printf("6、 编写算法,将一单链表就地逆置。");
createListR(*&La);
La = Reverse_1 (La);
printf("链表就地逆转后:");
printList(La);
system("pause");
return 0;
}
7、 编写算法,在一个双链表的第i个元素前插入一个元素。
/*7、 编写算法,在一个双链表的第i个元素前插入一个元素。*/
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct line {
struct line * prior;
ElemType data;
struct line * next;
}line;
line * insertLine(line * head, int data, int add) {
//新建数据域为data的结点
line * temp = (line*)malloc(sizeof(line));
temp->data = data;
temp->prior = NULL;
temp->next = NULL;
//插入到链表头,要特殊考虑
if (add == 1) {
temp->next = head;
head->prior = temp;
head = temp;
}
else {
int i = 0;
line * body = head;
//找到要插入位置的前一个结点
for (i = 1; i < add - 1; i++) {
body = body->next;
if (body == NULL) {
printf("插入位置有误\n");
break;
}
}
if (body) {
//判断条件为真,说明插入位置为链表尾
if (body->next == NULL) {
body->next = temp;
temp->prior = body;
}
else {
body->next->prior = temp;
temp->next = body->next;
body->next = temp;
temp->prior = body;
}
}
}
return head;
}
//输出链表的功能函数
void display(line * head) {
line * temp = head;
while (temp) {
if (temp->next == NULL) {
printf("%d\n", temp->data);
}
else {
printf("%d-", temp->data);
}
temp = temp->next;
}
}
line* initLine(line * head) {
int i = 0;
line * list = NULL;
head = (line*)malloc(sizeof(line));
head->prior = NULL;
head->next = NULL;
head->data = 1;
list = head;
for (i = 2; i <= 10; i++) {
line * body = (line*)malloc(sizeof(line));
body->prior = NULL;
body->next = NULL;
body->data = i;
list->next = body;
body->prior = list;
list = list->next;
}
return head;
}
int main() {
ElemType x;
int i;
printf("7、 编写算法,在一个双链表的第i个元素前插入一个元素。\n");
line * head = NULL;
printf("初始链表为:\n");
head = initLine(head);
display(head);
printf("在表中第 i 的位置插入新元素 x (input i and x):\n");
scanf("%d %d",&i,&x);
head = insertLine(head, x, i);
display(head);
system("pause");
return 0;
}
8、 编写算法,删除一个双链表的第i个元素。
/*8、 编写算法,删除一个双链表的第i个元素。*/
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct line {
struct line * prior;
ElemType data;
struct line * next;
} line;
//删除函数,其中,pos 表示要删除结点在双链表中的位置
line *Del_ith(line * p, int pos) {
int i = 0;
line * temp = p;
//遍历到被删除结点
for (i = 1; i < pos; i++) {
temp = temp->next;
if (temp == NULL) {
printf("删除位置有误!\n");
break;
}
}
if (temp) {
temp->prior->next = temp->next;
temp->next->prior = temp->prior;
free(temp);
// return p;
}
return p;
}
//输出链表的功能函数
void display(line * head) {
line * temp = head;
while (temp) {
if (temp->next == NULL) {
printf("%d\n", temp->data);
} else {
printf("%d-", temp->data);
}
temp = temp->next;
}
}
line* initLine(line * head) {
int i = 0;
line * list = NULL;
head = (line*)malloc(sizeof(line));
head->prior = NULL;
head->next = NULL;
head->data = 1;
list = head;
for (i = 2; i <= 10; i++) {
line * body = (line*)malloc(sizeof(line));
body->prior = NULL;
body->next = NULL;
body->data = i;
list->next = body;
body->prior = list;
list = list->next;
}
return head;
}
int main() {
int i;
printf("8、 编写算法,删除一个双链表的第i个元素。\n");
line * head = NULL;
printf("初始链表为:\n");
head = initLine(head);
display(head);
printf("删除一个双链表的第i个元素(input i):\n");
scanf("%d",&i);
head = Del_ith(head,i);
display(head);
system("pause");
return 0;
}
9、 编写算法,删除一升序单链表中所有值相同的多余元素,释放被删结点空间。
/*9、 编写算法,删除一升序单链表中所有值相同的多余元素,释放被删结点空间。*/
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElementType;
typedef struct LNode {
ElementType data;
struct LNode *Next;
} LNode,*List;
/*尾插法建立链表L */
void createListR(LNode *&L) {
LNode *s, *r; //s用来指向新申请的结点,r始终指向L的终端结点
ElementType x;
L = (LNode *)malloc(sizeof(struct LNode));//申请L的头结点空间
L->Next = NULL;
r = L;//r指向头结点,因为此时头结点就是终端结点
printf("\n(尾插法)请依次输入链表元素(以-999作结束标志):\n");
while(1) {
//循环申请结点来接收输入缓冲区中的元素,直到遇到-999结束接收
scanf("%d",&x);
if(x == -999) break;
s = (LNode *)malloc(sizeof(struct LNode));//s指向新申请的结点
s->data = x;//用新申请的结点来接收输入的元素
r->Next = s;//用r来接纳新结点
r = r->Next;//r指向终端结点,以便于接纳下一个到来的结点