if(L.list[i]==e)
returni+1;
return0;
}
intInsertList(SeqList*L,inti,DataTypee)
/*在顺序表的第i个位置插入元素e,插入成功返回1,如果插入位置不合法返回-1,顺序表满返回0*/
{
intj;
if(i<1||i>L->length+1)/*在插入元素前,判断插入位置是否合法*/
{
printf("插入位置i不合法!
\n");
return-1;
}
elseif(L->length>=ListSize)/*在插入元素前,判断顺序表是否已经满,不能插入元素*/
{
printf("顺序表已满,不能插入元素。
\n");
return0;
}
else
{
for(j=L->length;j>=i;j--)/*将第i个位置以后的元素依次后移*/
L->list[j]=L->list[j-1];
L->list[i-1]=e;/*插入元素到第i个位置*/
L->length=L->length+1;/*将顺序表长增1*/
return1;
}
}
intDeleteList(SeqList*L,inti,DataType*e)
{
intj;
if(L->length<=0)
{
printf("顺序表已空不能进行删除!
\n");
return0;
}
elseif(i<1||i>L->length)
{
printf("删除位置不合适!
\n");
return-1;
}
else
{
*e=L->list[i-1];
for(j=i;j<=L->length-1;j++)
L->list[j-1]=L->list[j];
L->length=L->length-1;
return1;
}
}
intListLength(SeqListL)
{
returnL.length;
}
voidClearList(SeqList*L)
{
L->length=0;
}
voidMergeList(SeqListA,SeqListB,SeqList*C);/*合并顺序表A和B中元素的函数声明*/
voidmain()
{
inti,flag;
DataTypea[]={6,11,11,23};
DataTypeb[]={2,10,12,12,21};
DataTypee;
SeqListA,B,C;/*声明顺序表A,B和C*/
InitList(&A);/*初始化顺序表A*/
InitList(&B);/*初始化顺序表B*/
InitList(&C);/*初始化顺序表C*/
for(i=1;i<=sizeof(a)/sizeof(a[0]);i++)/*将数组a中的元素插入到顺序表A中*/
{
if(InsertList(&A,i,a[i-1])==0)
{
printf("位置不合法");
return;
}
}
for(i=1;i<=sizeof(b)/sizeof(b[0]);i++)/*将数组b中元素插入到顺序表B中*/
{
if(InsertList(&B,i,b[i-1])==0)
{
printf("位置不合法");
return;
}
}
printf("顺序表A中的元素:
\n");
for(i=1;i<=A.length;i++)/*输出顺序表A中的每个元素*/
{
flag=GetElem(A,i,&e);/*返回顺序表A中的每个元素到e中*/
if(flag==1)
printf("%4d",e);
}
printf("\n");
printf("顺序表B中的元素:
\n");
for(i=1;i<=B.length;i++)/*输出顺序表B中的每个元素*/
{
flag=GetElem(B,i,&e);/*返回顺序表B中的每个元素到e中*/
if(flag==1)
printf("%4d",e);
}
printf("\n");
printf("将在A中出现B的元素合并后C中的元素:
\n");
MergeList(A,B,&C);/*将在顺序表A和B中的元素合并*/
for(i=1;i<=C.length;i++)/*显示输出合并后C中所有元素*/
{
flag=GetElem(C,i,&e);
if(flag==1)
printf("%4d",e);
}
printf("\n");
getch();
}
voidMergeList(SeqListA,SeqListB,SeqList*C)
/*合并顺序表A和B的元素到C中,并保持元素非递减排序*/
{
inti,j,k;
DataTypee1,e2;
i=1;j=1;k=1;
while(i<=A.length&&j<=B.length)
{
GetElem(A,i,&e1);/*取出顺序表A中的元素*/
GetElem(B,j,&e2);/*取出顺序表B中的元素*/
if(e1<=e2)/*比较顺序表A和顺序表B中的元素*/
{
InsertList(C,k,e1);/*将较小的一个插入到C中*/
i++;/*往后移动一个位置,准备比较下一个元素*/
k++;
}
else
{
InsertList(C,k,e2);/*将较小的一个插入到C中*/
j++;/*往后移动一个位置,准备比较下一个元素*/
k++;
}
}
while(i<=A.length)/*如果A中元素还有剩余,这时B中已经没有元素*/
{
GetElem(A,i,&e1);
InsertList(C,k,e1);/*将A中剩余元素插入到C中*/
i++;
k++;
}
while(j<=B.length)/*如果B中元素还有剩余,这时A中已经没有元素*/
{
GetElem(B,j,&e2);
InsertList(C,k,e2);/*将B中剩余元素插入到C中*/
j++;
k++;
}
C->length=A.length+B.length;/*C的表长等于A和B的表长的和*/
}
●链式表的非递减数列合并
/*包含头文件*/
#include
#include
#include
/*宏定义和单链表类型定义*/
#defineListSize100
typedefintDataType;
typedefstructNode
{
DataTypedata;
structNode*next;
}ListNode,*LinkList;
voidMergeList(LinkListA,LinkListB,LinkList*C);/*将单链表A和B的元素合并到C中的函数声明*/
voidInitList(LinkList*head)
/*将单链表初始化为空。
动态生成一个头结点,并将头结点的指
针域置为空。
*/
{
if((*head=(LinkList)malloc(sizeof(ListNode)))
==NULL)/*为头结点分配一个存储空间*/
exit(-1);
(*head)->next=NULL;
/*将单链表的头结点指针域置为空*/
}
intListEmpty(LinkListhead)
/*判断单链表是否为空,就是通过判断头结点的指针域是否为空
*/
{
if(head->next==NULL)/*判断
单链表头结点的指针域是否为空*/
return1;
/*当单链表为空时,返回1;否则返回0*/
else
return0;
}
ListNode*Get(LinkListhead,inti)
/*查找单链表中第i个结点。
查找成功返回该结点的指针表示成
功;否则返回NULL表示失败。
*/
{
ListNode*p;
intj;
if(ListEmpty(head))/*在查找第i个元素之前,
判断链表是否为空*/
returnNULL;
if(i<1)/*在查找第i个元
素之前,判断该序号是否合法*/
returnNULL;
j=0;
p=head;
while(p->next!
=NULL&&j
{
p=p->next;
j++;
}
if(j==i)
returnp;/*找到第i个结点
,返回指针p*/
else
returnNULL;/*如果没有找到第i个元
素,返回NULL*/
}
ListNode*LocateElem(LinkListhead,DataTypee)
/*查找线性表中元素值为e的元素,查找成功将对应元素的结点
指针返回,否则返回NULL表示失败。
*/
{
ListNode*p;
p=head->next;/*指针p指向第一个结点*/
while(p)
{
if(p->data!
=e)/*找到与e相等的元素,返
回该序号*/
p=p->next;
else
break;
}
returnp;
}
intLocatePos(LinkListhead,DataTypee)
/*查找线性表中元素值为e的元素,查找成功将对应元素的序号
返回,否则返回0表示失败。
*/
{
ListNode*p;
inti;
if(ListEmpty(head))/*在查找第i个元
素之前,判断链表是否为空*/
return0;
p=head->next;/*指针p指向第一
个结点*/
i=1;
while(p)
{
if(p->data==e)/*找到与e相等的
元素,返回该序号*/
returni;
else
{
p=p->next;
i++;
}
}
if(!
p)/*如果
没有找到与e相等的元素,返回0,表示失败*/
return0;
}
intInsertList(LinkListhead,inti,DataTypee)
/*在单链表中第i个位置插入一个结点,结点的元素值为e。
插入
成功返回1,失败返回0*/
{
ListNode*p,*pre;/*定义指向第i个元素的前
驱结点指针pre,指针p指向新生成的结点*/
intj;
pre=head;/*指针p指向头结
点*/
j=0;
while(pre->next!
=NULL&&j,即第i个结点的前驱结点*/
{
pre=pre->next;
j++;
}
if(!
pre)
/*如果没找到,说明插入位置错误*/
{
printf("插入位置错");
return0;
}
/*新生成一个结点,并将e赋值给该结点的数据域*/
if((p=(ListNode*)malloc(sizeof(ListNode)))==NULL)
exit(-1);
p->data=e;
/*插入结点操作*/
p->next=pre->next;
pre->next=p;
return1;
}
intDeleteList(LinkListhead,inti,DataType*e)
/*删除单链表中的第i个位置的结点。
删除成功返回1,失败返回
0*/
{
ListNode*pre,*p;
intj;
pre=head;
j=0;
while(pre->next!
=NULL&&pre->next->next!
=NULL&&j{
pre=pre->next;
j++;
}
if(j!
=i-1)/*如果没找到要
删除的结点位置,说明删除位置错误*/
{
printf("删除位置错误");
return0;
}
/*指针p指向单链表中的第i个结点,并将该结点的数据
域值赋值给e*/
p=pre->next;
*e=p->data;
/*将前驱结点的指针域指向要删除结点的下一个结点,
也就是将p指向的结点与单链表断开*/
pre->next=p->next;
free(p);/*释放p指向的结
点*/
return1;
}
intListLength(LinkListhead)
{
ListNode*p;
intcount=0;
p=head;
while(p->next!
=NULL)
{
p=p->next;
count++;
}
returncount;
}
voidDestroyList(LinkListhead)
{
ListNode*p,*q;
p=head;
while(p!
=NULL)
{
q=p;
p=p->next;
free(q);
}
}
voidmain()
{
inti;
DataTypea[]={6,7,9,14,37,45,65,67};
DataTypeb[]={3,7,11,34,45,89};
LinkListA,B,C;/*声明单链表A和B*/
ListNode*p;
InitList(&A);/*初始化单链表A*/
InitList(&B);/*初始化单链表B*/
for(i=1;i<=sizeof(a)/sizeof(a[0]);i++)/*将数组a中元素插入到单链表A中*/
{
if(InsertList(A,i,a[i-1])==0)
{
printf("位置不合法");
return;
}
}
for(i=1;i<=sizeof(b)/sizeof(b[0]);i++)/*将数组b中元素插入单链表B中*/
{
if(InsertList(B,i,b[i-1])==0)
{
printf("位置不合法");
return;
}
}
printf("单链表A中的元素有%d个:
\n",ListLength(A));
for(i=1;i<=ListLength(A);i++)/*输出单链表A中的每个元素*/
{
p=Get(A,i);/*返回单链表A中的每个结点的指针*/
if(p)
printf("%4d",p->data);/*输出单链表A中的每个元素*/
}
printf("\n");
printf("单链表B中的元素有%d个:
\n",ListLength(B));
for(i=1;i<=ListLength(B);i++)
{
p=Get(B,i);/*返回单链表B中的每个每个结点的指针*/
if(p)
printf("%4d",p->data);/*输出单链表B中的每个元素*/
}
printf("\n");
MergeList(A,B,&C);/*将单链表A和B中的元素合并到C中*/
printf("将单链表A和B的元素合并到C中后,C中的元素有%d个:
\n",ListLength(C));
for(i=1;i<=ListLength(C);i++)
{
p=Get(C,i);/*返回单链表C中每个结点的指针*/
if(p)
printf("%4d",p->data);/*显示输出C中所有元素*/
}
printf("\n");
getch();
}
voidMergeList(LinkListA,LinkListB,LinkList*C)
/*单链表A和B中的元素非递减排列,将单链表A和B中的元素合并到C中,C中的元素仍按照非递减排列*/
{
ListNode*pa,*pb,*pc;/*定义指向单链表A,B,C的指针*/
pa=A->next;
pb=B->next;
*C=A;/*将单链表A的头结点作为C的头结点*/
(*C)->next=NULL;
pc=*C;
/*依次将链表A和B中较小的元素存入链表C中*/
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;/*如果A中的元素小于或等于B中的元素,将A中的元素的结点作为C的结点*/
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;/*如果A中的元素大于B中的元素,将B中的元素的结点作为C的结点*/
pc=pb;
pb=pb->next;
}
}
pc->next=pa?
pa:
pb;/*将剩余的结点插入C中*/
free(B);/*释放B的头结点*/
}
实验2栈和队列的应用
一、实验目的
1、掌握栈和队列这两种抽象数据类型的特点,并能在相应的应用问题中正确选用它们。
2、熟练掌握栈类型的两种实现方法。
3、熟练掌握循环队列和链队列的基本操作实现算法。
二、实验内容及步骤
1、用程序设计语言实现栈和队列的抽象数据类型。
2、在第一题的基础上完成以下选择:
选择一:
1)设计并实现括号匹配算法。
2)用队列实现在屏幕上打印杨辉三角。
选择二:
分别用栈和队列实现迷宫问题求解。
选择三:
分别用栈和队列实现一个列车调度系统。
三、实验步骤与调试过程
首先只只置操作数栈为空,表达式起始符“#”为运算符栈的栈底元素,依次读入表达式中每个字符,直至整个表达式求值完毕。
四、实验结果
五、疑难小结
对栈的顺序存储结构用了更深刻的了解,同时也对程序设计能力有了提高,加深了对栈先进后出性质的理解,对数组的应用也十分熟练。
六、主要算法:
●括号匹配算法。
#include
#include
#include
#include"string.h"
/*宏定义和链栈类型定义*/
typedefcharDataType;
intMatch(DataTypee,DataTypech);
typedefstructnode
{
DataTypedata;
structnode*next;
}LStackNode,*LinkStack;
voidInitStack(LinkStack*top)
/*将链栈初始化为空。
动态生成头结点,并将头结点的指针域置为空。
*/
{
if((*top=(LinkStack)malloc(sizeof(LStackNode)))==NULL)/*为头结点分配一个存储空间*/
exit(-1);
(*top)->next=NULL;/*将