实验内容:建立一有序的链表并实现线性表的基本操作(初始化、插入、删除、查找等)。
实验要求:
(1)根据需求完成程序整体设计。
(2)根据整体设计,设计各个函数。
(3)完成程序代码,上机调试运行,得到实验结果。
(4)整理实验数据,撰写实验报告。
实验目的:
本实验项目可以支撑课程目标1,2,3,4,5。通过本实验使学生掌握线性表的链式存储结构的特点,掌握线性表的基本操作(初始化、插入、删除、查找数据元素等)在链式存储结构上的实现,进行算法设计和程序实现,并能测试验证算法与程序的正确性。
#include <stdio.h>
#include <stdlib.h>
#define ERROR 0;
#define OK 1;
typedef int ElemType;
typedef struct Node
{
ElemType data;
struct Node * next; //指针域next 存放下一个地址
}Node, *LinkList;//用typedef定义过后的LinkList相当于struct Node *
// Node * 相当于struct Node *;
void main()
{
void menu();
void InitList(LinkList *L);//把单链表置空
#if(0)
void CreateFromHead(LinkList L);//头插法给单链表插入数据
#endif;
void CreateFromTail(LinkList L);//尾插法给单链表插入数据
int ListLength(LinkList L);//求单链表的长度
Node * Get(LinkList L,int i,int changdu);//在单链表L中查找第i个结点(按序号查找)
Node * Locate(LinkList L,ElemType key);//在单链表L中查找第i个结点(按值查找)
int InsertList(LinkList L,int i,ElemType value);//在单链表中插入结点以及结点中的值
int DeleteList(LinkList L,int i,ElemType *e);//在单链表中根据结点删除元素
void PrintList(LinkList *L);
int choose;//输入选择变量
LinkList L;//头指针
int changdu;//定义变量接收单链表的长度
int i;//定义查找第i个结点变量
Node *address;//定义返回的指向地址变量的指针
int zhi;//定义要输入查找的值变量
int position,value;//定义位置和值变量
int shanchu;//定义要删除的结点
int cun;//定义存储变量储存删除的值
printf("请输入选择操作:\n");
menu();//调用菜单函数
printf("输入-1退出系统:\n");
scanf("%d",&choose);
while(choose!=-1)
{
switch(choose)
{
case 1:
InitList(&L);
printf("已把单链表置为空\n");break;
case 2:
printf("请输入要尾插入的数据:\n");
CreateFromTail(L);break;
case 3:
changdu = ListLength(L);
printf("单链表的长度为%d\n",changdu);break;
case 4:
printf("请输入要查找的结点0<m<=%d\n",ListLength(L));
scanf("%d",&i);
address = Get(L,i,ListLength(L));
printf("结点%d在内存中的地址为%d 值为%d\n",i,address,address->data);break;
case 5:
printf("请输入要查找的值:\n");
scanf("%d",&zhi);
address = Locate(L,zhi);
printf("值%d 在内存中的地址为%d \n",address->data,address);break;
case 6:
printf("请选择要插入的位置和插入的值(中间用空格空开):\n");
scanf("%d %d",&position,&value);
InsertList(L,position,value);break;
case 7:
printf("请输入要删除的结点:\n");
scanf("%d",&shanchu);
DeleteList(L,shanchu,&cun);break;
case 8:
PrintList(&L);break;
}
printf("\n请再次输入要选择的项:\n");
scanf("%d",&choose);
}
#if(0)
CreateFromHead(L);
#endif;
}
void menu()
{
printf("可供输入:\n");
printf("1.初始化单链表\t");
printf("2.尾插法插入数据(结束插入换行crtl+Z再换行)\t");
printf("3.单链表长度\t");
printf("4.按序号查找\t");
printf("5.按值查找\n");
printf("6.插入数据\t");
printf("7.删除操作\t");
printf("8.打印链表数据:\n");
printf("请输入:\n");
}
void InitList(LinkList *L)
{
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
}
#if(0)
void CreateFromHead(LinkList L)
{
Node *s;
int c;
int flag = 1;
while(flag)
{
scanf("%d",&c);
if(c!=000)
{
s=(Node*)malloc(sizeof(Node));
s->data = c;
s->next = L->next;
L = s;
}
else flag = 0;
}
}
#endif;
void CreateFromTail(LinkList L)
{
Node *r,*s;//r为尾指针,s指向新申请的结点
int flag = 1;
int n;
r = L;
while(scanf("%d",&n)!=EOF)//结束条件为输入完数据换行打crtl+z再换行
{
s = (Node*)malloc(sizeof(Node));
s->data = n;
r->next = s;
r = s;
}
r->next = NULL;
}
int ListLength(LinkList L)
{
Node *p;
int j;
p = L->next;
j = 0; /*用来存放单链表的长度*/
while(p!=NULL)//直到L->next指向的地址为NULL循环结束
{
p = p->next;
j++;
}
return j;//返回单链表的长度
}
Node* Get(LinkList L,int i,int changdu)
{
int j;
Node *p;
if(i<=0 || i>changdu)
{
return ERROR;
}else
{
p = L;j=0; //从头结点开始扫描
while((p->next != NULL) && (j<i) )
{
p = p->next; //扫描下一结点p = p->next相当于i = i++
j++;
}
if(i == j) return p;
}
}
Node * Locate(LinkList L,ElemType key)
{
Node *p;
p = L->next;
while(p != NULL)
if(p->data != key)
p = p->next;
else break;
return p;
}
int InsertList(LinkList L,int i,ElemType value)
{
Node *pre,*s;
int k;
if(i<=0) return ERROR;
pre = L;k = 0; //从“头”开始,查找第i - 1个结点
while( (pre!=NULL) && (k<i-1))
{
pre = pre->next;
k = k+1;
} //查找第i-1个结点
if(pre == NULL)
{
printf("插入位置不合理!");
return ERROR;
}
s = (Node*)malloc(sizeof(Node)); //申请一个新的结点s
s->data = value;
s->next = pre->next;
pre->next = s;
printf("插入成功!\n");
return OK;
}
int DeleteList(LinkList L,int i,ElemType *e)
{
Node *pre,*r;
int k;
pre = L;k = 0;
while((pre->next!=NULL) && (k<i-1))
{
pre = pre->next;
k = k+1;
}
if(pre->next == NULL)
{
printf("删除结点的位置i不合理!");
return ERROR;
}
r = pre->next;
pre->next = r->next;
*e = r->data;
free(r);
printf("删除成功,删除的值为%d",*e);
return OK;
}
void PrintList(LinkList *L)
{
Node *p,*v;
p = *L;//把头指针的地址给p
v = p->next;//p的next域给指针变量v
printf("单链表数据为:\n");
while(v)//当v指向空时结束循环
{
printf("%d ",v->data);
v = v->next;//v->next赋给v相当于v=v++(不是真的等于V++)
}
}
//输入效果如下:
// 注意:尾插元素后先按Enter键然后再按Ctrl+Z+Enter组合键结束输入。
效果如下图:
输入提示效果图: