实验目的:
(1)理解线性表的类型定义
(2)熟练掌握链表的存储结构
(3)熟练掌握链表的基本操作算法
实验要求:
编写一个包含链表的初始化、插入、删除、查找等基本操作的程序。
代码:
#include <stdio.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 80 /*线性表存储空间的初始分配量*/
#define LISTINCREMENT 10 /* 线性表存储空间的分配增量*/
#define ElemType int
#define OVERFLOW -2
typedef struct{ //链表类型
//Link head, tail; //分别指向线性表中的头结点和最后一个结点
int length,listsize;
ElemType *elem;//指示线性链表中数据元素的个数
}LinkList;
enum status {OK=1,ERROR};
typedef int Status;
void insertruction (void);
Status InitList_L(LinkList &L); //构造一个空的线性链表
Status ListInsert_L(LinkList &L,int i,ElemType);//在带头结点的单链线性表L的第i个元素插入元素e
Status ListDelete_L(LinkList &L,int i,ElemType &e);//在带头结点的单链线线性表L中,删除第i个元素,并由其他值返回其值
int LocateElem_L(LinkList,ElemType);
Status (*compare)(ElemType,ElemType);//在静态单链线性表L中查找元素
void printList(LinkList &L);//
void DestroyList_Link(LinkList);//销毁线性链表L,L不再存在
main ()
{
LinkList myLinkList;
int choice;
int item;
ElemType deleted_value;
int loc;
if (InitList_L(myLinkList)!=1) return 0;
insertruction ();/*显示菜单*/
printf ("?");
scanf ("%d",&choice);
while (choice!=4){
switch(choice){
case 1:
printf("Enter tow integer:");
scanf("/n%d%d",&loc,&item);
if (ListInsert_L(myLinkList,loc,item)==1)
printf("ListInsert ok/n");
else
printf("ListInsert error/n");
printList(myLinkList);
break;
case 2:
printf("Enter an integer(location):");
scanf("/n%d",&loc);
if (ListDelete_L(myLinkList,loc,deleted_value)==1)
printf("ListDelete is %d/n",deleted_value);
else
printf("ListDelete error/n");
printList(myLinkList);
break;
case 3:
printf("Enter a value to be finded:");
scanf("/n%d",&item);
if (LocateElem_L(myLinkList,item)==0)
printf("not find %d./n",item);
else
printf("%d is locate %d./n",item,LocateElem_L(myLinkList,item));
break;
default:
printf("Invalid choice./n/n");
insertruction ();
break;
}
printf("?");
scanf("%d",&choice);
}
DestroyList_Link(myLinkList);
printf("End of run./n");
return 0;
}
void insertruction (void)
{
printf("Enter your choice: /n"
"1 to insert an element into the LinkList. /n"
"2 to delete an element into the LinkList. /n"
"3 to find an element in the LinkList. /n"
"4 to end./n");
}
Status InitList_L(LinkList &L) {
// 构造一个空的线性表
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if (!L.elem){
printf("Linklist not Init. No memory available./n");
exit(OVERFLOW);
}
L.length=0;
L.listsize=LIST_INIT_SIZE;
return OK;
} // InitList_Link
int LocateElem_L(LinkList L, ElemType e){
// 在顺序表中查询第一个满足判定条件的数据元素,
// 若存在,则返回它的位序,否则返回 0
ElemType i,*p;
i=1; // i 的初值为第 1 元素的位序
p=L.elem; // p 的初值为第 1 元素的存储位置
//i=S[0].cur;
while(i<=L.length && !(*compare)(*p++,e)) ++i;
if(i<=L.length)
return i;
else return 0;
} // LocateElem_Link
Status ListInsert_L(LinkList &L, int i, ElemType e) {
/* 在顺序表L的第 i 个元素之前插入新的元素e,*/
/* i 的合法范围为 1≤i≤L.length+1*/
ElemType *newbase, *q,*p;
if (i<1||i>L.length+1) return ERROR;/* 插入位置不合法*/
if (L.length>=L.listsize) {// 当前存储空间已满,增加分配
newbase= (ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if (!newbase) exit(OVERFLOW);// 存储分配失败
L.elem=newbase;// 新基址
L.listsize += LISTINCREMENT; // 增加存储容量
}
q=&(L.elem[i-1]); // q 指示插入位置
for(p= &(L.elem[L.length-1]); p>=q;--p)*(p+1)=*p; // 插入位置及之后的元素右移
*q=e; // 插入e
++L.length; // 表长增1
return OK;
}// ListInsert_Link
Status ListDelete_L(LinkList &L, int i, ElemType &e) {
ElemType *p, *q;
if ((i<1)||(i>L.length)) return ERROR; // 删除位置不合法
p=&(L.elem[i-1]); // p 为被删除元素的位置
e=*p; // 被删除元素的值赋给 e
q=L.elem+L.length-1; // 表尾元素的位置
for (++p;p<=q;++p)*(p-1)=*p;// 被删除元素之后的元素左移
--L.length; // 表长减1
return OK;
} // ListDelete-Sq
/*打印线性顺序表*/
void printList(LinkList &L) {
ElemType *q;/*int k;*/
if (L.length>0){
printf ("LinkList is: ");
/*for (k=0;k<L->length;k++){
q=&(L->elem[k]);
printf("%d,",*q);}
printf("/n");*/
for (q=L.elem;q<L.elem+L.length;q++){
printf("%d,",*q);
}
printf("/n");
}
else
printf ("List is empty./n/n");
}
void DestroyList_Link(LinkList L)
{
//free(L.elem);
L.listsize=0;
L.length=0;
free(L.elem);
}//DestroyList_Link