顺序表
1.实验目标
熟练掌握线性表的顺序存储结构。
熟练掌握顺序表的有关算法设计。
根据具体问题的需要,设计出合理的表示数据的顺序结构,并设计相关算法。
2.实验内容和要求
实验要求
顺序表结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
比如存储、算法实现放入文件:seqList.h
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
实验任务
编写算法实现下列问题的求解。
<1>求顺序表中第i个元素(函数),若不存在,报错。
实验测试数据基本要求:
第一组数据:顺序表长度n≥10,i分别为5,n,0,n+1,n+2
第二组数据:顺序表长度n=0,i分别为0,2
<2>在第i个结点前插入值为x的结点。
实验测试数据基本要求:
第一组数据:顺序表长度n≥10,x=100, i分别为5,n,n+1,0,1,n+2
第二组数据:顺序表长度n=0,x=100,i=5
<3>删除顺序表中第i个元素结点。
实验测试数据基本要求:
第一组数据:顺序表长度n≥10,i分别为5,n,1,n+1,0
第二组数据:顺序表长度n=0, i=5
<4>在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。
实验测试数据基本要求:
顺序表元素为 (10,20,30,40,50,60,70,80,90,100),
x分别为25,85,110和8
<5>将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
实验测试数据基本要求:
第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9,10,20,30,40,50,60)
第二组数据:顺序表元素为 (10,20,30,40,50,60,70,80,90,100)
<6>求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。
实验测试数据基本要求:
第一组
第一个顺序表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个顺序表元素为 (1,2,3,4,5,6,7,8,9,10,18,20,30)
第二组
第一个顺序表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个顺序表元素为 (2,4,5,7,8,9,12,22)
第三组
第一个顺序表元素为 ()
第二个顺序表元素为 (1,2,3,4,5,6,7,8,9,10)
<7>删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。
实验测试数据基本要求:
第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9)
第二组数据:顺序表元素为 (1,1,2,2,2,3,4,5,5,5,6,6,7,7,8,8,9)
第三组数据:顺序表元素为 (1,2,3,4,5,5,6,7,8,8,9,9,9,9,9)
顺序表扩展实验
<1> 递增有序顺序表L1、L2,对2表进行合并,并使得合并后成为一个集合,集合的元素放回L1表中保存,要求时间性能最好。
<2>(递增有序)顺序表表示集合A、B,实现:
C=AB,C=AB,C=A-B
A=AB,A=AB,A=A-B
<3>(递增有序)顺序表表示集合A、B,判定A是否B的子集。
<4>(2011)(15 分)一个长度为L(L≥1)的升序序列S,处在第L/2个位置的数称为S 的中位数。例如,若序列S1=(11, 13, 15, 17, 19),则S1 的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2, 4, 6, 8, 20),则S1 和S2 的中位数是11。
现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C 或C++语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度。
3.数据结构设计
#ifndef EXP1_H_INCLUDED
#define EXP1_H_INCLUDED
#include<stdio.h>
#include<stdlib.h>
struct Slist
{
int listlen;
int data[100];
};
typedef struct Slist slist;
slist createlist(void) //构建顺序表。
{
slist newlist;
int i,a;
printf("输入顺序表的长度:\n");
scanf("%d",&a);
printf("依次输入顺序表元素:\n");
for(i=0;i<a;i=i+1)
{
scanf("%d",&newlist.data[i]);
}
newlist.listlen = a;
return (newlist);
}
int listgetelement(slist newlist,int k);
int listinsert(slist seqlist,int i,int x);
int listdelete(slist seqlist,int i);
void listorderinsert(slist seqlist,int x);
int listnewlist(slist seqlist);
void listnewx(slist newlist1,slist newlist2);
void listdeletex(slist newlist);
void listlinklisttofirst(slist list1,slist list2);
void listhelist(slist list1,slist list2);
void listbilist(slist list1,slist list2);
void listhexlist(slist list1,slist list2);
void listqlist(slist list1,slist list2);
void listbixlist(slist list1,slist list2);
void listqxlist(slist list1,slist list2);
int listzzlist(slist list1,slist list2);
void listzlistz(slist list1,slist list2);
void menu(void)
{
int m;
loop:
printf("实验任务:\n");
printf("<1>求顺序表中第i个元素(函数),若不存在,报错。\n");
printf("<2>在第i个结点前插入值为x的结点。\n");
printf("<3>删除顺序表中第i个元素结点。\n");
printf("<4>在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。\n");
printf("<5>将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。\n");
printf("<6>求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。\n");
printf("<7>删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。\n");
printf("\n");
printf("顺序表扩展实验:\n");
printf("<8> 递增有序顺序表L1、L2,对2表进行合并,并使得合并后成为一个集合,集合的元素放回L1表中保存,要求时间性能最好。\n");
printf("<9>(递增有序)顺序表表示集合A、B,实现:C=A与B的交集\n");
printf("<10>C=A与B的并集\n");
printf("<11>C=A-B\n");
printf("<12>A=A与B的交集\n");
printf("<13>A=A与B的并集\n");
printf("<14>A=A-B\n");
printf("<15>(递增有序)顺序表表示集合A、B,判定A是否B的子集。\n");
printf("<16>现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。\n");
printf("\n");
printf("<17>清屏。\n");
printf("<18>退出。\n");
printf("\n");
scanf("%d",&m);
printf("\n");
switch(m)
{
case 1:
{
slist l;
int i;
l = createlist();
printf("输入元素的位置:\n");
scanf("%d",&i);
listgetelement(l,i);
goto loop;
}
case 2:
{
slist l;
int i,x;
l = createlist();
printf("输入结点的位置:\n");
scanf("%d",&i);
printf("输入值:\n");
scanf("%d",&x);
listinsert(l,i,x);
goto loop;
}
case 3:
{
slist l;
int i;
l = createlist();
printf("输入元素的位置:\n");
scanf("%d",&i);
listdelete(l,i);
goto loop;
}
case 4:
{
slist l;
int x;
l = createlist();
printf("输入值:\n");
scanf("%d",&x);
listorderinsert(l,x);
goto loop;
}
case 5:
{
slist l;
l = createlist();
listnewlist(l);
goto loop;
}
case 6:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listnewx(l1,l2);
goto loop;
}
case 7:
{
slist l;
l = createlist();
listdeletex(l);
goto loop;
}
case 8:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listlinklisttofirst(l1,l2);
goto loop;
}
case 9:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listhelist(l1,l2);
goto loop;
}
case 10:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listbilist(l1,l2);
goto loop;
}
case 11:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listqlist(l1,l2);
goto loop;
}
case 12:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listhexlist(l1,l2);
goto loop;
}
case 13:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listbixlist(l1,l2);
goto loop;
}
case 14:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listqxlist(l1,l2);
goto loop;
}
case 15:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listzzlist(l1,l2);
goto loop;
}
case 16:
{
slist l1,l2;
l1 = createlist();
l2 = createlist();
listzlistz(l1,l2);
goto loop;
}
case 18:
{
goto mmo;
}
case 17:
{
system("cls");
goto loop;
}
default:
{
printf("输入错误。\n");
goto loop;
}
}
mmo: system("cls");
}
int listgetelement(slist newlist,int k) //实验任务 <1>求顺序表中第i个元素(函数),若不存在,报错。
{
if(k<1 || k>newlist.listlen)
{
printf("第%d个元素不在顺序表中。\n",k);
system("pause");
return 0;
}
else
{
printf("第%d个元素为:\n",k);
printf("%d\n",newlist.data[k-1]);
system("pause");
return 1;
}
}
int listinsert(slist seqlist,int i,int x) //<2>在第i个结点前插入值为x的结点。
{
int len;
len = seqlist.listlen + 1;
int datax[len];
int j,k;
if(i<1 || i>len)
{
printf("该结点不在顺序表中。\n");
system("pause");
return 0;
}
else
{
for(j=0,k=0;j<len;j=j+1)
{
if(j==i-1)
{
datax[j] = x;
}
else
{
datax[j] = seqlist.data[k];
k = k+1;
}
}
}
printf("插入结点后的顺序表:\n");
for(j=0;j<len;j=j+1)
{
seqlist.data[j] = datax[j];
printf("%d\t",seqlist.data[j]);
}
seqlist.listlen = len;
system("pause");
return 1;
}
int listdelete(slist seqlist,int i) //<3>删除顺序表中第i个元素结点。
{
int datax[seqlist.listlen];
int j,k;
if(i<1 || i>seqlist.listlen)
{
printf("该结点不在顺序表中。\n");
system("pause");
return 0;
}
else
{
for(j=0,k=0;j<seqlist.listlen;j=j+1)
{
if(j==i-1)
{
k = k;
}
else
{
datax[k] = seqlist.data[j];
k = k+1;
}
}
}
printf("删除结点后的顺序表:\n");
for(j=0;j<k;j=j+1)
{
seqlist.data[j] = datax[j];
printf("%d\t",seqlist.data[j]);
}
seqlist.listlen = k;
system("pause");
return 1;
}
void listorderinsert(slist seqlist,int x) //<4>在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。
{
int i,j,k;
int datax[seqlist.listlen+1];
for(i=0,j=0;i<seqlist.listlen;i=i+1)
{
if(x>seqlist.data[i])
{
j = j+1;
}
else
{
j = j;
}
}
for(i=0,k=0;i<seqlist.listlen+1;i=i+1)
{
if(i==j)
{
datax[i] = x;
}
else
{
datax[i] = seqlist.data[k];
k = k+1;
}
}
printf("插入结点后的顺序表:\n");
seqlist.listlen = seqlist.listlen+1;
for(j=0;j<seqlist.listlen;j=j+1)
{
seqlist.data[j] = datax[j];
printf("%d\t",seqlist.data[j]);
}
system("pause");
}
int listnewlist(slist seqlist) //<5>将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
{
int i,j,k;
slist newlist[2];
newlist[0].listlen = 0;
newlist[1].listlen = 0;
for(i=0,j=0,k=0;i<seqlist.listlen;i=i+1)
{
if(seqlist.data[i]%2!=0)
{
newlist[0].data[j] = seqlist.data[i];
j = j+1;
newlist[0].listlen = j;
}
else
{
newlist[1].data[k] = seqlist.data[i];
k = k+1;
newlist[1].listlen = k;
}
}
printf("原来的顺序表:\n");
for(i=0;i<seqlist.listlen;i=i+1)
{
printf("%d\t",seqlist.data[i]);
}
printf("\n");
printf("原顺序表的奇数项:\n");
for(j=0;j<newlist[0].listlen;j=j+1)
{
printf("%d\t",newlist[0].data[j]);
}
printf("\n");
printf("原顺序表的偶数项:\n");
for(k=0;k<newlist[1].listlen;k=k+1)
{
printf("%d\t",newlist[1].data[k]);
}
printf("\n");
system("pause");
return 1;
}
void listnewx(slist newlist1,slist newlist2) //<6>求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。
{
int i,j,k;
slist newlist3;
for(i=0,k=0;i<newlist1.listlen;i=i+1)
{
for(j=0;j<newlist2.listlen;j=j+1)
{
if(newlist1.data[i]==newlist2.data[j])
{
newlist3.data[k] = newlist1.data[i];
k = k+1;
break;
}
}
}
newlist3.listlen = k+1;
printf("新的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
printf("%d\t",newlist3.data[i]);
}
system("pause");
}
void listdeletex(slist newlist) //<7>删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。
{
int n=0,i;
slist alist;
alist.data[n] = newlist.data[0];
for(i=0;i<newlist.listlen;i=i+1)
{
if(newlist.data[i]!=alist.data[n])
{
n = n+1;
alist.data[n] = newlist.data[i];
}
}
alist.listlen = n+1;
newlist.listlen = alist.listlen;
n = i;
printf("新的顺序表为:\n");
for(i=0;i<alist.listlen;i=i+1)
{
newlist.data[i] = alist.data[i];
printf("%d\t",newlist.data[i]);
}
n = n+i;
printf("\n移动元素次数:\n%d\n",n);
system("pause");
}
void listlinklisttofirst(slist list1,slist list2) //顺序表扩展实验 <1>递增有序顺序表L1、L2,对2表进行合并,并使得合并后成为一个集合,集合的元素放回L1表中保存,要求时间性能最好。
{
int i,j,k;
slist list3;
i = 0;
j = 0;
k = 0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
list3.data[k] = list2.data[j];
j = j+1;
k = k+1;
}
else if(list1.data[i]>list2.data[j])
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
else
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
if(i==list1.listlen && j<list2.listlen)
{
while(j<list2.listlen)
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
}
else if(i<list1.listlen && j==list2.listlen)
{
while(i<list1.listlen)
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
list3.listlen = k;
list1.listlen = list3.listlen;
printf("新的顺序表为:\n");
for(i=0,k=0;i<list1.listlen;i=i+1)
{
list1.data[i] = list3.data[k];
printf("%d\t",list1.data[i]);
k = k+1;
}
printf("\n");
system("pause");
}
void listhelist(slist list1,slist list2) //<2><1>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i = 0;
j = 0;
k = 0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
j = j+1;
}
else if(list1.data[i]>list2.data[j])
{
j = j+1;
}
else
{
i = i+1;
}
}
list3.listlen = k;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
printf("%d\t",list3.data[i]);
}
system("pause");
}
void listbilist(slist list1,slist list2) //<2><2>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i =0;
j =0;
k =0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
j = j+1;
k = k+1;
}
else if(list1.data[i]>list2.data[j])
{
list3.data[k] = list2.data[j];
j = j+1;
k = k+1;
}
else
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
}
}
if(i==list1.listlen)
{
while(j<list2.listlen)
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
}
else if(j==list2.listlen)
{
while(i<list1.listlen)
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
list3.listlen = k;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
printf("%d\t",list3.data[i]);
}
system("pause");
}
void listqlist(slist list1,slist list2) //<2><3>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i =0;
j =0;
k =0;
while(i<list1.listlen)
{
if(list1.data[i]<list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
}
else if(list1.data[i]==list2.data[j])
{
i = i+1;
j = j+1;
}
else
{
j = j+1;
}
}
list3.listlen = k;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
printf("%d\t",list3.data[i]);
}
system("pause");
}
void listhexlist(slist list1,slist list2) //<2><4>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i = 0;
j = 0;
k = 0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
j = j+1;
}
else if(list1.data[i]>list2.data[j])
{
j = j+1;
}
else
{
i = i+1;
}
}
list3.listlen = k;
list1.listlen = list3.listlen;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
list1.data[i] = list3.data[i];
printf("%d\t",list1.data[i]);
}
system("pause");
}
void listbixlist(slist list1,slist list2) //<2><5>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i =0;
j =0;
k =0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
j = j+1;
k = k+1;
}
else if(list1.data[i]>list2.data[j])
{
list3.data[k] = list2.data[j];
j = j+1;
k = k+1;
}
else
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
}
}
if(i==list1.listlen)
{
while(j<list2.listlen)
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
}
else if(j==list2.listlen)
{
while(i<list1.listlen)
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
list3.listlen = k;
list1.listlen = list3.listlen;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
list1.data[i] = list3.data[i];
printf("%d\t",list1.data[i]);
}
system("pause");
}
void listqxlist(slist list1,slist list2) //<2><6>(递增有序)顺序表表示集合A、B,实现:
{
slist list3;
int i,j,k;
i =0;
j =0;
k =0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]<list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
}
else if(list1.data[i]==list2.data[j])
{
i = i+1;
j = j+1;
}
else
{
j = j+1;
}
}
if(i<list1.listlen && j==list2.listlen)
{
while(i<list1.listlen)
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
}
}
list3.listlen = k;
list1.listlen = list3.listlen;
printf("合成的顺序表为:\n");
for(i=0;i<k;i=i+1)
{
list1.data[i] = list3.data[i];
printf("%d\t",list1.data[i]);
}
system("pause");
}
int listzzlist(slist list1,slist list2) //<3>(递增有序)顺序表表示集合A、B,判定A是否B的子集。
{
int i,j;
i = 0;
j = 0;
while(i<list1.listlen)
{
if(list1.data[i]>list2.data[j])
{
j = j+1;
}
else if(list1.data[i]==list2.data[j])
{
i = i+1;
j = j+1;
}
else
{
printf("A不是B的子集。\n");
system("pause");
return 0;
}
}
printf("A是B的子集。\n");
system("pause");
return 1;
}
void listzlistz(slist list1,slist list2) //<4>现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。
{
slist list3;
int i,j,k;
i = 0;
j = 0;
k = 0;
while(i<list1.listlen && j<list2.listlen)
{
if(list1.data[i]==list2.data[j])
{
list3.data[k] = list1.data[i];
i = i+1;
k = k+1;
list3.data[k] = list2.data[j];
j = j+1;
k = k+1;
}
else if(list1.data[i]>list2.data[j])
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
else
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
if(i==list1.listlen && j<list2.listlen)
{
while(j<list2.listlen)
{
list3.data[k] = list2.data[j];
k = k+1;
j = j+1;
}
}
else if(i<list1.listlen && j==list2.listlen)
{
while(i<list1.listlen)
{
list3.data[k] = list1.data[i];
k = k+1;
i = i+1;
}
}
printf("中位数为:\n");
list3.listlen = k;
k = k/2-1;
i = 0;
while(i!=k)
{
i = i+1;
}
printf("%d\n",list3.data[i]);
system("pause");
}
#endif
#include"seqList.h"
int main(void)
{
menu();
}
单链表
1.实验目标
熟练掌握线性表的链式存储结构。
熟练掌握单链表的有关算法设计。
根据具体问题的需要,设计出合理的表示数据的链式存储结构,并设计相关算法。
2.实验内容和要求
本次实验中的链表结构指带头结点的单链表;
单链表结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
比如存储、算法实现放入文件:linkedList.h
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
实验任务
编写算法实现下列问题的求解。
<1>尾插法创建单链表,打印创建结果。
<2>头插法创建单链表,打印创建结果。
<3>销毁单链表。
<4>求链表长度。
<5>求单链表中第i个元素(函数),若不存在,报错。
实验测试数据基本要求:
第一组数据:单链表长度n≥10,i分别为5,n,0,n+1,n+2
第二组数据:单链表长度n=0,i分别为0,2
<6>在第i个结点前插入值为x的结点。
实验测试数据基本要求:
第一组数据:单链表长度n≥10,x=100, i分别为5,n,n+1,0,1,n+2
第二组数据:单链表长度n=0,x=100,i=5
<7>链表中查找元素值为x的结点,成功返回结点指针,失败报错。
实验测试数据基本要求:
单链表元素为 (1,3,6,10,15,16,17,18,19,20)
x=1,17,20,88
<8>删除单链表中第i个元素结点。
实验测试数据基本要求:
第一组数据:单链表长度n≥10,i分别为5,n,1,n+1,0
第二组数据:单链表长度n=0, i=5
<9>在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。
实验测试数据基本要求:
单链表元素为 (10,20,30,40,50,60,70,80,90,100),
x分别为25,85,110和8
<10>将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
实验测试数据基本要求:
第一组数据:单链表元素为 (1,2,3,4,5,6,7,8,9,10,20,30,40,50,60)
第二组数据:单链表元素为 (10,20,30,40,50,60,70,80,90,100)
<11>求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。
实验测试数据基本要求:
第一组
第一个单链表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个单链表元素为 (1,2,3,4,5,6,7,8,9,10,18,20,30)
第二组
第一个单链表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个单链表元素为 (2,4,5,7,8,9,12,22)
第三组
第一个单链表元素为 ()
第二个单链表元素为 (1,2,3,4,5,6,7,8,9,10)
<12>删除递增有序单链表中的重复元素,要求时间性能最好。
实验测试数据基本要求:
第一组数据:单链表元素为 (1,2,3,4,5,6,7,8,9)
第二组数据:单链表元素为 (1,1,2,2,2,3,4,5,5,5,6,6,7,7,8,8,9)
第三组数据:单链表元素为 (1,2,3,4,5,5,6,7,8,8,9,9,9,9,9)
<13>递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。
实验测试数据基本要求:
第一组
第一个单链表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个单链表元素为 (1,2,3,4,5,6,7,8,9,10,18,20,30)
第二组
第一个单链表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个单链表元素为 (2,4,5,7,8,9,12,22)
第三组
第一个单链表元素为 ()
第二个单链表元素为 (1,2,3,4,5,6,7,8,9,10)
单链表扩展实验
<1>(递增有序)单链表表示集合A、B,实现:
C=AB,C=AB,C=A-B
A=AB,A=AB,A=A-B
<2>(递增有序)单链表表示集合A、B,判定A是否B的子集。
<3>(2009)(15分)已知一个带有表头结点的单链表,结点结构如下图。假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data值,并返回1;否则,只返回0。要求:
(1)描述算法的基本设计思想
(2)描述算法的详细实现步骤
(3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用C 或C++语言实现),关键之处请给出简要注释。
<4>(2011)(15 分)一个长度为L(L≥1)的升序序列S,处在第L/2个位置的数称为S 的中位数。例如,若序列S1=(11, 13, 15, 17, 19),则S1 的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2, 4, 6, 8, 20),则S1 和S2 的中位数是11。现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C 或C++语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度。
3.数据结构设计
#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED
#include<stdio.h>
#include<stdlib.h>
struct slnode
{
int data;
struct slnode *next;
};
typedef struct slnode node;
node * createlist(void);
node * createlisth(void);
void destroylist(node *l);
int listlength(node *l);
void getelement(node *l,int i);
int listinsert(node *l,int i,int x);
node * listlocate(node *l,int x);
int listdelete(node *l,int i);
void listinsertx(node *l,int x);
void listnewdlist(node *l);
void listnewlist(node *l1,node *l2);
void listdeletedx(node *l);
void listlinklist(node *la,node *lb);
int listhelist(node *la,node *lb);
void listbilist(node *la,node *lb);
void listqlist(node *la,node *lb);
void listhexlist(node *la,node *lb);
void listbixlist(node *la,node *lb);
void listqxlist(node *la,node *lb);
int listzzlist(node *la,node *lb);
int listkx(node *l,int k);
void listzlistz(node *la,node *lb);
void menu(void)
{
int m;
loopx:
printf("实验任务:\n");
printf("<1>尾插法创建单链表,打印创建结果。\n");
printf("<2>头插法创建单链表,打印创建结果。\n");
printf("<3>销毁单链表。\n");
printf("<4>求链表长度。\n");
printf("<5>求单链表中第i个元素(函数),若不存在,报错。\n");
printf("<6>在第i个结点前插入值为x的结点。\n");
printf("<7>链表中查找元素值为x的结点,成功返回结点指针,失败报错。\n");
printf("<8>删除单链表中第i个元素结点。\n");
printf("<9>在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。\n");
printf("<10>将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。\n");
printf("<11>求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。\n");
printf("<12>删除递增有序单链表中的重复元素,要求时间性能最好。\n");
printf("<13>递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。\n");
printf("\n");
printf("单链表扩展实验:\n");
printf("<14>(递增有序)顺序表表示集合A、B,实现:C=A与B的交集\n");
printf("<15>C=A与B的并集\n");
printf("<16>C=A-B\n");
printf("<17>A=A与B的交集\n");
printf("<18>A=A与B的并集\n");
printf("<19>A=A-B\n");
printf("<20>(递增有序)单链表表示集合A、B,判定A是否B的子集。\n");
printf("<21>已知一个带有表头结点的单链表,结点结构如下图。假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data值,并返回1;否则,只返回0。\n");
printf("<22>现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。\n");
printf("\n");
printf("<23>清屏。\n");
printf("<24>退出。\n");
printf("\n");
scanf("%d",&m);
printf("\n");
switch(m)
{
case 1:
{
node *l;
l = createlist();
destroylist(l);
goto loopx;
}
case 2:
{
node *l;
l = createlisth();
destroylist(l);
goto loopx;
}
case 3:
{
node *l;
l = createlist();
destroylist(l);
goto loopx;
}
case 4:
{
node *l;
l = createlist();
listlength(l);
destroylist(l);
goto loopx;
}
case 5:
{
node *l;
l = createlist();
int i;
printf("输入单链表中元素的位置:\n");
scanf("%d",&i);
getelement(l,i);
destroylist(l);
goto loopx;
}
case 6:
{
node *l;
l = createlist();
int i,x;
printf("输入结点的值和位置:\n");
scanf("%d %d",&x,&i);
listinsert(l,i,x);
destroylist(l);
goto loopx;
}
case 7:
{
node *l;
l = createlist();
int x;
printf("输入结点的值:\n");
scanf("%d",&x);
listlocate(l,x);
destroylist(l);
goto loopx;
}
case 8:
{
node *l;
l = createlist();
int i;
printf("输入单链表中元素的位置:\n");
scanf("%d",&i);
listdelete(l,i);
destroylist(l);
goto loopx;
}
case 9:
{
node *l;
l = createlist();
int x;
printf("输入结点的值:\n");
scanf("%d",&x);
listinsertx(l,x);
destroylist(l);
goto loopx;
}
case 10:
{
node *l;
l = createlist();
listnewdlist(l);
destroylist(l);
goto loopx;
}
case 11:
{
node *l1;
l1 = createlist();
node *l2;
l2 = createlist();
listnewlist(l1,l2);
destroylist(l1);
destroylist(l2);
goto loopx;
}
case 12:
{
node *l;
l = createlist();
listdeletedx(l);
destroylist(l);
goto loopx;
}
case 13:
{
node *la,*lb;
la = createlist();
lb = createlist();
listlinklist(la,lb);
destroylist(la);
goto loopx;
}
case 14:
{
node *la,*lb;
la = createlist();
lb = createlist();
listhelist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 15:
{
node *la,*lb;
la = createlist();
lb = createlist();
listbilist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 16:
{
node *la,*lb;
la = createlist();
lb = createlist();
listqlist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 17:
{
node *la,*lb;
la = createlist();
lb = createlist();
listhexlist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 18:
{
node *la,*lb;
la = createlist();
lb = createlist();
listbixlist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 19:
{
node *la,*lb;
la = createlist();
lb = createlist();
listqxlist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 20:
{
node *la,*lb;
la = createlist();
lb = createlist();
listzzlist(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 21:
{
node *l;
l = createlist();
int k;
printf("输入想要查找的结点的倒数位置:\n");
scanf("%d",&k);
listkx(l,k);
destroylist(l);
goto loopx;
}
case 22:
{
node *la,*lb;
la = createlist();
lb = createlist();
listzlistz(la,lb);
destroylist(la);
destroylist(lb);
goto loopx;
}
case 23:
{
system("cls");
goto loopx;
}
case 24:
{
goto mmo;
}
default:
{
printf("输入错误。\n");
goto loopx;
}
}
mmo:system("cls");
}
node * createlist(void) //实验任务 <1>尾插法创建单链表,打印创建结果。
{
node *l;
int x;
node *u,*r;
l = (node *)malloc(sizeof(node));
l->next = NULL;
r = l;
printf("依次输入结点的值:(输入9999停止)\n");
scanf("%d",&x);
while(x!=9999)
{
u = (node *)malloc(sizeof(node));
u->data = x;
u->next = NULL;
r->next = u;
r = u;
scanf("%d",&x);
}
if(l->next==NULL)
{
return l;
}
r = l->next;
printf("创建的链表为:\n");
while(r!=NULL)
{
printf("%d\t",r->data);
r = r->next;
}
printf("\n");
system("pause");
return l;
}
node * createlisth(void) //<2>头插法创建单链表,打印创建结果。
{
node *l;
node *u,*r;
int x;
l = (node *)malloc(sizeof(node));
l->next = NULL;
printf("依次输入结点的值:(输入9999停止)\n");
scanf("%d",&x);
while(x!=9999)
{
u = (node *)malloc(sizeof(node));
u->data = x;
u->next = l;
l = u;
scanf("%d",&x);
}
r = l;
printf("创建的链表为:\n");
while(r->next!=NULL)
{
printf("%d\t",r->data);
r = r->next;
}
printf("\n");
system("pause");
return l;
}
void destroylist(node *l) //<3>销毁单链表。
{
node *q;
while(l!=NULL)
{
q = l->next;
free(l);
l = q;
}
}
int listlength(node *l) //<4>求链表长度。
{
int len=0;
node *p;
p = l->next;
while(p!=NULL)
{
len = len+1;
p = p->next;
}
printf("链表的长度为:%d\n",len);
system("pause");
return len;
}
void getelement(node *l,int i) //<5>求单链表中第i个元素(函数),若不存在,报错。
{
node *p;
int j = 1;
p = l->next;
while(j!=i && p!=NULL)
{
j = j+1;
p = p->next;
}
if(p==NULL)
{
printf("这个元素不在单链表中。\n");
system("pause");
}
else
{
printf("第%d个元素为:\n%d\n",i,p->data);
system("pause");
}
}
int listinsert(node *l,int i,int x) //<6>在第i个结点前插入值为x的结点。
{
node *p,*s,*k;
int j = 1;
p = l->next;
k = l->next;
s = (node *)malloc(sizeof(node));
while(j!=i && p!=NULL)
{
if(p!=k)
{
p = p->next;
j = j+1;
k = k->next;
}
else
{
p = p->next;
}
}
if(p==NULL)
{
if(i==j+1)
{
s->data = x;
s->next = p;
k->next = s;
l = l->next;
}
else
{
printf("输入错误。\n");
system("pause");
return 1;
}
}
else if(j==1)
{
s->data = x;
s->next = p;
l = s;
}
else
{
s->data = x;
s->next = p;
k->next = s;
l = l->next;
}
printf("插入结点后的链表为:\n");
p = l;
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
system("pause");
return 1;
}
node * listlocate(node *l,int x) //<7>链表中查找元素值为x的结点,成功返回结点指针,失败报错。
{
node *s;
s = l;
while(s!=NULL)
{
if(s->data==x)
{
printf("查找到相应结点。\n");
system("pause");
return s;
}
else
{
s = s->next;
}
}
printf("未找到值为%d的结点。\n",x);
system("pause");
return s;
}
int listdelete(node *l,int i) //<8>删除单链表中第i个元素结点。
{
node *p,*u;
int j=0;
p = l;
while(j!=i && p!=NULL)
{
p = p->next;
j = j+1;
}
if(p==NULL || j==0)
{
printf("输入错误。\n");
system("pause");
return 0;
}
else if(p->next==NULL && p!=NULL)
{
u = p;
free(u);
}
else
{
u = p->next;
p->next = u->next;
free(u);
}
p = l->next;
printf("删除结点后的单链表为:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
system("pause");
return 1;
}
void listinsertx(node *l,int x) //<9>在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。
{
node *p,*s,*u;
p = l;
s = l->next;
u = (node *)malloc(sizeof(node));
u->data = x;
while(p->next!=NULL)
{
if(s->data>x)
{
break;
}
p = p->next;
s = s->next;
}
u->next = p->next;
p->next = u;
s = l->next;
printf("新的单链表为:\n");
while(s!=NULL)
{
printf("%d\t",s->data);
s = s->next;
}
printf("\n");
system("pause");
}
void listnewdlist(node *l) //<10>将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
{
node *p,*la,*lb;
node *s,*u,*k;
p = l->next;
la = (node *)malloc(sizeof(node));
lb = (node *)malloc(sizeof(node));
la->next = NULL;
lb->next = NULL;
while(p!=NULL)
{
if(p->data%2!=0)
{
break;
}
p = p->next;
}
if(p!=NULL)
{
s = (node *)malloc(sizeof(node));
s->data = p->data;
s->next = NULL;
u = s;
la->next = s;
while(p!=NULL)
{
if(p->data%2!=0 && p->data!=la->next->data)
{
s = (node *)malloc(sizeof(node));
s->data = p->data;
s->next = NULL;
u->next = s;
u = s;
}
p = p->next;
}
}
p = l->next;
while(p!=NULL)
{
if(p->data%2==0)
{
break;
}
p = p->next;
}
if(p!=NULL)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
u = k;
lb->next = k;
while(p!=NULL)
{
if(p->data%2==0 && p->data!=lb->next->data)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
u->next = k;
u = k;
}
p = p->next;
}
}
p = l->next;
printf("原来的单链表:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
p = la->next;
printf("单链表的奇数项:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
destroylist(la);
p = lb->next;
printf("单链表的偶数项:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
destroylist(lb);
system("pause");
}
void listnewlist(node *l1,node *l2) //<11>求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。
{
node *l3,*p,*q,*s,*r;
p = l1->next;
q = l2->next;
l3 = (node *)malloc(sizeof(node));
l3->next = NULL;
while(p!=NULL && q!=NULL)
{
if(p->data==q->data)
{
r = (node *)malloc(sizeof(node));
r->data = p->data;
r->next = NULL;
s = r;
l3->next = r;
break;
}
else if(p->data>q->data)
{
q = q->next;
}
else
{
p = p->next;
}
}
if(p==NULL || q==NULL)
{
printf("无相同的元素。\n");
free(l3);
system("pause");
return;
}
p = p->next;
q = q->next;
while(p!=NULL && q!=NULL)
{
if(p->data==q->data)
{
r = (node *)malloc(sizeof(node));
r->data = p->data;
r->next = NULL;
s->next = r;
s = r;
p = p->next;
q = q->next;
}
else if(p->data>q->data)
{
q = q->next;
}
else
{
p = p->next;
}
}
printf("新的单链表为:\n");
s = l3->next;
while(s!=NULL)
{
printf("%d\t",s->data);
s = s->next;
}
printf("\n");
destroylist(l3);
system("pause");
}
void listdeletedx(node *l) //<12>删除递增有序单链表中的重复元素,要求时间性能最好。
{
node *s,*p,*u;
s = l;
p = l->next;
while(p!=NULL)
{
if(s->data==p->data)
{
u = p;
p = p->next;
s->next = p;
free(u);
}
else
{
s = p;
p = p->next;
}
}
printf("新的单链表为:\n");
s = l->next;
while(s!=NULL)
{
printf("%d\t",s->data);
s = s->next;
}
printf("\n");
system("pause");
}
void listlinklist(node *la,node *lb) //<13>递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。
{
node *p,*q,*s,*k;
p = la->next;
q = lb->next;
free(lb);
if(p!=NULL && q!=NULL && p->data>q->data)
{
s = p->next;
k = q->next;
la->next = q;
while(p->data>=k->data && k!=NULL)
{
if(p->data<=k->data)
{
q->next = p;
q = k;
k = k->next;
}
else
{
q = q->next;
k = k->next;
}
}
if(k==NULL)
{
q->next = p;
}
}
else if(p!=NULL && q!=NULL && p->data<=q->data)
{
s = p->next;
k = q->next;
la->next = p;
}
if(p==NULL && q!=NULL)
{
la->next = q;
s = NULL;
k = q->next;
}
else if(p!=NULL && q==NULL)
{
la->next = p;
s = p->next;
k = NULL;
}
while(s!=NULL && k!=NULL)
{
if(p->data>q->data)
{
if(p->data<=k->data)
{
q->next = p;
q = k;
k = k->next;
}
else
{
q = q->next;
k = k->next;
}
}
else if(p->data<q->data)
{
if(q->data<s->data)
{
p->next = q;
p = s;
s = s->next;
}
else
{
p = p->next;
s = s->next;
}
}
else
{
p->next = q;
p = s;
s = s->next;
if(p->data<=k->data)
{
q->next = p;
}
else
{
q->next = k;
}
q = k;
k = k->next;
}
}
if(s==NULL && k!=NULL && p!=NULL && q!=NULL)
{
p->next = q;
}
else if(s!=NULL && k==NULL && p!=NULL && q!=NULL )
{
q->next = p;
}
printf("新的单链表为:\n");
p = la->next;
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
system("pause");
}
int listhelist(node *la,node *lb) //单链表扩展实验 <1><1>(递增有序)单链表表示集合A、B,实现:
{
node *lc,*p,*s,*k,*q;
p = la->next;
s = lb->next;
lc = (node *)malloc(sizeof(node));
while(p!=NULL && s!=NULL && p->data!=s->data)
{
if(p->data>s->data)
{
s = s->next;
}
else
{
p = p->next;
}
}
if(p==NULL || s==NULL)
{
printf("A与B无交集。\n");
free(lc);
system("pause");
return 0;
}
else
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
q = k;
lc->next = k;
p = p->next;
s = s->next;
}
while(p!=NULL && s!=NULL)
{
if(p->data==s->data)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
q->next = k;
q = k;
p = p->next;
s = s->next;
}
else if(p->data>s->data)
{
s = s->next;
}
else
{
p = p->next;
}
}
printf("新生成的单链表为:\n");
q = lc->next;
while(q!=NULL)
{
printf("%d\t",q->data);
q = q->next;
}
printf("\n");
destroylist(lc);
system("pause");
return 1;
}
void listbilist(node *la,node *lb) //<1><2>(递增有序)单链表表示集合A、B,实现:
{
node *p,*q,*lc,*s,*k;
p = la->next;
q = lb->next;
lc = (node *)malloc(sizeof(node));
k = (node *)malloc(sizeof(node));
lc->next = k;
k->next = NULL;
s = k;
if(p->data>q->data)
{
k->data = q->data;
q = q->next;
}
else
{
k->data = p->data;
p = p->next;
}
while(p!=NULL && q!=NULL)
{
if(p->data==q->data)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
p = p->next;
q = q->next;
}
else if(p->data>q->data)
{
k = (node *)malloc(sizeof(node));
k->data = q->data;
k->next = NULL;
s->next = k;
s = k;
q = q->next;
}
else
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
p = p->next;
}
}
if(p==NULL && q!=NULL)
{
while(q!=NULL)
{
k = (node *)malloc(sizeof(node));
k->data = q->data;
k->next = NULL;
s->next = k;
s = k;
q = q->next;
}
}
else if(p!=NULL && q==NULL)
{
while(p!=NULL)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
p = p->next;
}
}
printf("新生成的单链表为:\n");
s = lc->next;
while(s!=NULL)
{
printf("%d\t",s->data);
s = s->next;
}
printf("\n");
destroylist(lc);
system("pause");
}
void listqlist(node *la,node *lb) //<1><3>(递增有序)单链表表示集合A、B,实现:
{
node *lc,*q,*p,*s,*k;
p = la->next;
q = lb->next;
lc = (node *)malloc(sizeof(node));
k = (node *)malloc(sizeof(node));
lc->next = k;
k->next = NULL;
s = k;
while(p!=NULL && q!=NULL && p->data==q->data)
{
p = p->next;
}
k->data = p->data;
p = p->next;
while(p!=NULL && q!=NULL)
{
if(p->data==q->data)
{
p = p->next;
q = q->next;
}
else if(p->data>q->data)
{
q = q->next;
}
else
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
p = p->next;
}
}
if(p!=NULL && q==NULL)
{
while(p!=NULL)
{
k = (node *)malloc(sizeof(node));
k->data = p->data;
k->next = NULL;
s->next = k;
s = k;
p = p->next;
}
}
printf("新生成的单链表为:\n");
s = lc->next;
while(s!=NULL)
{
printf("%d\t",s->data);
s = s->next;
}
printf("\n");
destroylist(lc);
system("pause");
}
void listhexlist(node *la,node *lb) //<1><4>(递增有序)单链表表示集合A、B,实现:
{
node *p,*q,*s,*k;
p = la->next;
q = lb->next;
k = la;
while(p!=NULL && q!=NULL)
{
if(p->data<q->data)
{
k->next = p->next;
free(p);
p = k->next;
}
else if(p->data==q->data)
{
p = p->next;
k = k->next;
q = q->next;
}
else
{
q = q->next;
}
}
if(p!=NULL && q==NULL)
{
k->next = NULL;
while(p!=NULL)
{
s = p->next;
free(p);
p = s;
}
}
printf("新生成的单链表为:\n");
k = la->next;
while(k!=NULL)
{
printf("%d\t",k->data);
k = k->next;
}
printf("\n");
system("pause");
}
void listbixlist(node *la,node *lb) //<1><5>(递增有序)单链表表示集合A、B,实现:
{
node *p,*q,*s,*k;
p = la;
q = lb->next;
s = p->next;
while(s!=NULL && q!=NULL)
{
if(s->data>=q->data)
{
k = (node *)malloc(sizeof(node));
k->data = q->data;
p->next = k;
k->next = s;
p = k;
q = q->next;
}
else
{
s = s->next;
p = p->next;
}
}
if(s==NULL && q!=NULL)
{
while(q!=NULL)
{
k = (node *)malloc(sizeof(node));
k->data = q->data;
p->next = k;
k->next = NULL;
p = k;
q = q->next;
}
}
p = la->next;
printf("新生成的单链表为:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
system("pause");
}
void listqxlist(node *la,node *lb) //<1><6>(递增有序)单链表表示集合A、B,实现:
{
node *p,*q,*s;
p = la;
q = lb->next;
s = p->next;
while(s!=NULL && q!=NULL)
{
if(s->data==q->data)
{
p->next = s->next;
free(s);
s = p->next;
}
else if(s->data>q->data)
{
q = q->next;
}
else
{
p = p->next;
s = s->next;
}
}
p = la->next;
printf("新生成的单链表为:\n");
while(p!=NULL)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
system("pause");
}
int listzzlist(node *la,node *lb) //<2>(递增有序)单链表表示集合A、B,判定A是否B的子集。
{
node *p,*q;
p = la->next;
q = lb->next;
while(p!=NULL)
{
if(p->data==q->data)
{
p = p->next;
q = q->next;
}
else if(p->data<q->data)
{
printf("A不是B的子集。\n");
system("pause");
return 0;
}
else
{
q = q->next;
}
}
printf("A是B的子集。\n");
system("pause");
return 1;
}
int listkx(node *l,int k) // <3>已知一个带有表头结点的单链表,结点结构如下图。假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data值,并返回1;否则,只返回0。
{
int i;
node *p,*s;
p = l->next;
s = l->next;
for(i=1;i<k;i=i+1)
{
s = s->next;
}
if(s==NULL)
{
printf("无相应结点。\n");
system("pause");
return 0;
}
else
{
while(s->next!=NULL)
{
p = p->next;
s = s->next;
}
}
printf("结点的值为:\n");
printf("%d\n",p->data);
system("pause");
return 1;
}
void listzlistz(node *la,node *lb) // <4>现有两个等长升序序列A 和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A 和B 的中位数。
{
int i=1,j=1;
node *p,*q,*k;
p = la->next;
q = lb->next;
while(p!=NULL)
{
p = p->next;
i = i+1;
}
p = la->next;
while(p!=NULL && q!=NULL && j!=i)
{
if(p->data>=q->data)
{
k = q;
j = j+1;
q = q->next;
}
else
{
k = p;
j = j+1;
p = p->next;
}
}
printf("中位数为:\n");
printf("%d\n",k->data);
system("pause");
}
#endif // LINKEDLIST_H_INCLUDED
#include"linkedList.h"
int main(void)
{
menu();
return 0;
}
栈
1.实验目标
熟练掌握栈的顺序存储结构和链式存储结构。
熟练掌握栈的有关算法设计,并在顺序栈和链栈上实现。
根据具体给定的需求,合理设计并实现相关结构和算法。
2.实验内容和要求
顺序栈的实验要求
顺序栈结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
链栈实验要求
本次实验中的链栈结构指带头结点的单链表;
链栈结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
顺序栈实验任务
设计并实现一个顺序栈,编写算法实现下列问题的求解。
<1>利用顺序栈实现将10进制数转换为16进制数。
第一组数据:4
第二组数据:11
第三组数据:254
第四组数据:1357
<2>对一个合法的数学表达式来说,其中的各大小括号“{”,“}”,“[”,“]”,“(”和“)”应是相互匹配的。设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
链栈实验任务
以带头结点的单链表表示链栈,编写算法实现下列问题的求解。
<1>利用顺序栈实现将10进制数转换为16进制数。
第一组数据:4
第二组数据:11
第三组数据:254
第四组数据:1357
<2>对一个合法的数学表达式来说,其中的各大小括号“{”,“}”,“[”,“]”,“(”和“)”应是相互匹配的。设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
栈的扩展实验
<1>假设栈的输入序列为1、2、3、…、n,设计算法实现对给定的一个序列,判定其是否是此栈合法的输出序列。
<2>假设栈的输入序列为1、2、3、…、n,设计算法求出所有可能的出栈序列。
<3>利用栈求解算术表达式的值。
3.数据结构设计
#ifndef STACKLIST_H_INCLUDED
#define STACKLIST_H_INCLUDED
#include<stdio.h>
#include<stdlib.h>
#define maxlen 10000
typedef struct iStack
{
int data[maxlen];
int top;
}seqistack;
typedef struct cStack
{
char data[maxlen];
int top;
}seqcstack;
typedef struct slnode
{
int data;
struct slnode *next;
}node;
typedef struct slcnode
{
char data;
struct slcnode *next;
}cnode;
void tentosixteen(void);
int chjudge(void);
int rightout(void);
int allrightout(void);
void finz(void);
void tts(void);
int ljudg(void);
void menu(void)
{
int m;
loop:
printf("顺序栈实验任务:\n");
printf("<1>利用顺序栈实现将10进制数转换为16进制数。\n");
printf("<2>设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。\n");
printf("\n");
printf("链栈实验任务:\n");
printf("<3>利用链栈实现将10进制数转换为16进制数。\n");
printf("<4>设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。\n");
printf("\n");
printf("栈扩展实验:\n");
printf("<5>假设栈的输入序列为1、2、3、...、n,设计算法实现对给定的一个序列,判定其是否是此栈合法的输出序列。\n");
printf("<6>假设栈的输入序列为1、2、3、...、n,设计算法求出所有可能的出栈序列。\n");
printf("<7>利用栈求解算术表达式的值。\n");
printf("\n");
printf("<8>清屏。\n");
printf("<9>退出。\n");
printf("\n");
scanf("%d",&m);
printf("\n");
switch(m)
{
case 1:
{
tentosixteen();
goto loop;
}
case 2:
{
chjudge();
goto loop;
}
case 3:
{
tts();
goto loop;
}
case 4:
{
ljudg();
goto loop;
}
case 5:
{
rightout();
goto loop;
}
case 6:
{
allrightout();
goto loop;
}
case 7:
{
finz();
goto loop;
}
case 8:
{
system("cls");
goto loop;
}
case 9:
{
goto mmo;
}
default:
{
printf("输入错误。\n");
system("pause");
goto loop;
}
}
mmo:system("cls");
}
void tentosixteen(void) //<1>利用顺序栈实现将10进制数转换为16进制数。
{
seqistack l;
int i,s;
printf("输入数字:\n");
scanf("%d",&s);
l.top = -1;
i = 0;
printf("转化为十六进制后:\n");
if(s>16)
{
while(s/16!=0)
{
l.data[i] = s%16;
l.top = l.top+1;
s = s/16;
i = i+1;
}
l.data[i] = s;
l.top = l.top+1;
for(i=l.top;i>=0;i=i-1)
{
switch(l.data[i])
{
case 10:printf("a");break;
case 11:printf("b");break;
case 12:printf("c");break;
case 13:printf("d");break;
case 14:printf("e");break;
case 15:printf("f");break;
default:printf("%d",l.data[i]);break;
}
}
printf("\n");
}
else
{
switch(s)
{
case 10:printf("a\n");break;
case 11:printf("b\n");break;
case 12:printf("c\n");break;
case 13:printf("d\n");break;
case 14:printf("e\n");break;
case 15:printf("f\n");break;
default:printf("%d\n",s);break;
}
}
system("pause");
}
int chjudge(void) //<2>设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
{
seqcstack l;
char s[80];
int i;
l.top = -1;
printf("输入表达式。(在表达式尾输入#)\n");
for(i=0;i<80;i=i+1)
{
scanf("%c",&s[i]);
if(s[i]=='#')
{
break;
}
}
for(i=0;s[i]!='\0';i=i+1)
{
if(s[i]=='(' || s[i]=='[' || s[i]=='{')
{
l.top = l.top+1;
l.data[l.top] = s[i];
}
else if(s[i]==')' && l.data[l.top]=='(')
{
l.top = l.top-1;
}
else if(s[i]==']' && l.data[l.top]=='[')
{
l.top = l.top-1;
}
else if(s[i]=='}' && l.data[l.top]=='{')
{
l.top = l.top-1;
}
}
if(l.top==-1)
{
printf("匹配。\n");
system("pause");
return 0;
}
else
{
printf("不匹配。\n");
system("pause");
return 1;
}
}
int rightout(void) //<1>假设栈的输入序列为1、2、3、...、n,设计算法实现对给定的一个序列,判定其是否是此栈合法的输出序列。
{
seqistack l,lo;
int x,y,len,p;
int i=0,j=0,k=0;
l.top = -1;
printf("输入序列长度。\n");
scanf("%d",&len);
while(len!=j)
{
l.data[j] = j+1;
j++;
l.top++;
}
if(len<=0)
{
printf("输入错误。\n");
return 0;
}
printf("输入出栈序列。\n");
while(len!=i)
{
scanf("%d",&lo.data[i]);
i = i+1;
}
x = lo.data[0];
y = x;
p = lo.data[0];
for(lo.top=0;i>lo.top;lo.top++)
{
k = lo.top;
if(lo.data[k]<lo.data[0])
{
if(lo.data[k]>x)
{
printf("不是合法的输出序列。\n");
system("pause");
return 0;
}
x = lo.data[k];
}
else
{
if(lo.data[k]>y)
{
y = lo.data[k];
}
if(p<y && p<lo.data[k])
{
if(y!=lo.data[k])
{
printf("不是合法的输出序列。\n");
system("pause");
return 0;
}
}
}
p = lo.data[k];
}
printf("是合法的输出序列。\n");
system("pause");
return 1;
}
void allpl(int q,int z,int m[])
{
int i,a,k,qs,y,j;
int p;
if(q==z-1)
{
k = 1;
qs = m[0];
y = qs;
p = m[0];
for(j=0;j<z;j=j+1)
{
if(m[j]<m[0])
{
if(m[j]>qs)
{
k = 0;
break;
}
qs = m[j];
}
else
{
if(m[j]>y)
{
y = m[j];
}
if(p<y && p<m[j])
{
if(y!=m[j])
{
k = 0;
break;
}
}
}
p = m[j];
}
if(k==1)
{
for(k=0;k<z;k=k+1)
{
printf("%d\t",m[k]);
}
printf("\n");
}
}
else
{
for(i=q;i<z;i=i+1)
{
a = m[i];
m[i] = m[q];
m[q] = a;
allpl(q+1,z,m);
a = m[i];
m[i] = m[q];
m[q] = a;
}
}
}
int allrightout(void) //<2>假设栈的输入序列为1、2、3、...、n,设计算法求出所有可能的出栈序列。
{
seqistack l;
int len;
int i=0,j,k;
printf("输入序列长度。\n");
scanf("%d",&len);
printf("\n");
while(len!=i)
{
l.data[i] = i+1;
i++;
l.top++;
}
if(len<=0)
{
printf("输入错误。\n");
return 0;
}
int m[len];
for(i=0;i<len;i=i+1)
{
m[i] = i+1;
}
j = 0;
k = len;
allpl(j,k,m);
system("pause");
return 1;
}
void finz(void) //<3>利用栈求解算术表达式的值。
{
char s[80];
char a[80];
int i=0,j=0;
int qc=0,hc=0;
int lss=-2;
seqcstack lf;
seqistack ls;
lf.top = -1;
ls.top = -1;
printf("输入表达式。(在表达式尾输入#)\n");
for(i=0;s[i]!='#';i=i+1)
{
scanf("%c",&s[i]);
if(s[i]=='#' && i!=0)
{
break;
}
}
for(i=0;s[i]!='#';i=i+1)
{
if(s[i]=='(')
{
qc++;
}
else if(s[i]==')')
{
hc++;
}
}
if(qc!=hc)
{
printf("表达式不合法。\n");
system("pause");
printf("\n");
return;
}
for(i=0;i<80;i=i+1)
{
a[i] = '#';
}
for(i=0;s[i]!='\0';i=i+1)
{
if(s[i]>='0' && s[i]<='9')
{
a[j] = s[i];
j = j+1;
if(s[i+1]<'0' || s[i+1]>'9')
{
ls.top++;
lss++;
ls.data[ls.top] = atoi(a);
//printf("%d\t",ls.top);
for(j=0;j<80;)
{
a[j] = '#';
j = j+1;
if(a[j]=='#')
{
break;
}
}
j = 0;
}
}
else
{
if(s[i]=='(')
{
lf.top++;
lf.data[lf.top] = s[i];
}
if(s[i]==')')
{
while(lf.data[lf.top]!='(')
{
switch(lf.data[lf.top])
{
case '+':ls.data[lss] = ls.data[lss]+ls.data[ls.top]; break;
case '-':ls.data[lss] = ls.data[lss]-ls.data[ls.top]; break;
case '*':ls.data[lss] = ls.data[lss]*ls.data[ls.top]; break;
case '/':ls.data[lss] = ls.data[lss]/ls.data[ls.top]; break;
}
ls.top--;
lss--;
lf.top--;
//printf("%d\n",ls.top);
}
lf.top--;
}
if(s[i]=='*' || s[i]=='/')
{
if(lf.data[lf.top]=='+' || lf.data[lf.top]=='-')
{
lf.top++;
lf.data[lf.top] = s[i];
}
else if(lf.data[lf.top]=='*' || lf.data[lf.top]=='/')
{
switch(lf.data[lf.top])
{
case '*':ls.data[lss] = ls.data[lss]*ls.data[ls.top]; break;
case '/':ls.data[lss] = ls.data[lss]/ls.data[ls.top]; break;
}
ls.top--;
lss--;
lf.data[lf.top] = s[i];
//printf("%d\n",ls.top);
}
else if(lf.data[lf.top]=='(')
{
lf.top++;
lf.data[lf.top] = s[i];
}
else if(lf.top<0)
{
lf.top++;
lf.data[lf.top] = s[i];
}
}
else if(s[i]=='+' || s[i]=='-')
{
if(lf.data[lf.top]=='(')
{
lf.top++;
lf.data[lf.top] = s[i];
}
else if(lf.top<0)
{
lf.top++;
lf.data[lf.top] = s[i];
}
else
{
while(lf.data[lf.top]!='(' && lf.top>=0)
{
switch(lf.data[lf.top])
{
case '+':ls.data[lss] = ls.data[lss]+ls.data[ls.top]; break;
case '-':ls.data[lss] = ls.data[lss]-ls.data[ls.top]; break;
case '*':ls.data[lss] = ls.data[lss]*ls.data[ls.top]; break;
case '/':ls.data[lss] = ls.data[lss]/ls.data[ls.top]; break;
}
ls.top--;
lss--;
lf.top--;
}
lf.top++;
lf.data[lf.top] = s[i];
}
}
if(s[i]=='#')
{
while(lf.top>=0)
{
switch(lf.data[lf.top])
{
case '+':ls.data[lss] = ls.data[lss]+ls.data[ls.top]; break;
case '-':ls.data[lss] = ls.data[lss]-ls.data[ls.top]; break;
case '*':ls.data[lss] = ls.data[lss]*ls.data[ls.top]; break;
case '/':ls.data[lss] = ls.data[lss]/ls.data[ls.top]; break;
}
ls.top--;
lss--;
lf.top--;
//printf("%d\n",ls.top);
}
}
}
}
//printf("%d\n",ls.top);
printf("\n");
printf("%d\n",ls.data[ls.top]);
printf("\n");
system("pause");
}
void tts(void) //<1>利用链栈实现将10进制数转换为16进制数。
{
node *l,*r,*p;
int i,s;
l = (node *)malloc(sizeof(node));
l->next = NULL;
p = l->next;
printf("输入数字:\n");
scanf("%d",&s);
i = 0;
printf("转化为十六进制后:\n");
if(s>16)
{
while(s/16!=0)
{
r = (node *)malloc(sizeof(node));
r->data = s%16;
r->next = p;
p = r;
s = s/16;
}
r = (node *)malloc(sizeof(node));
r->data = s;
r->next = p;
p = r;
l->next = p;
r = l->next;
for(i=0;r!=NULL;i=i+1)
{
switch(r->data)
{
case 10:printf("a");break;
case 11:printf("b");break;
case 12:printf("c");break;
case 13:printf("d");break;
case 14:printf("e");break;
case 15:printf("f");break;
default:printf("%d",r->data);break;
}
r = r->next;
}
printf("\n");
}
else
{
switch(s)
{
case 10:printf("a\n");break;
case 11:printf("b\n");break;
case 12:printf("c\n");break;
case 13:printf("d\n");break;
case 14:printf("e\n");break;
case 15:printf("f\n");break;
default:printf("%d\n",s);break;
}
}
r = l;
while(r!=NULL)
{
l = l->next;
free(r);
r = l;
}
system("pause");
}
int ljudg(void) //<2>链栈设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
{
cnode *l,*p,*r;
char s[80];
int i;
l = (cnode *)malloc(sizeof(cnode));
l->next = NULL;
r = l;
printf("输入表达式。(在表达式尾输入#)\n");
for(i=0;i<80;i=i+1)
{
scanf("%c",&s[i]);
if(s[i]=='#')
{
break;
}
}
for(i=0;s[i]!='\0';i=i+1)
{
if(s[i]=='(' || s[i]=='[' || s[i]=='{')
{
p = (cnode *)malloc(sizeof(cnode));
p->data = s[i];
r->next = p;
p->next = NULL;
r = p;
}
else if(s[i]==')' && p->data=='(')
{
r = l;
while(r->next!=p)
{
r = r->next;
}
free(p);
p = r;
p->next = NULL;
}
else if(s[i]==']' && p->data=='[')
{
r = l;
while(r->next!=p)
{
r = r->next;
}
free(p);
p = r;
p->next = NULL;
}
else if(s[i]=='}' && p->data=='{')
{
r = l;
while(r->next!=p)
{
r = r->next;
}
free(p);
p = r;
p->next = NULL;
}
}
if(l->next==NULL)
{
printf("匹配。\n");
free(l);
system("pause");
return 0;
}
else
{
printf("不匹配。\n");
r = l;
while(r!=NULL)
{
l = l->next;
free(r);
r = l;
}
system("pause");
return 1;
}
}
#endif // STACKLIST_H_INCLUDED
#include"stacklist.h"
int main(void)
{
menu();
}