实验1.2 链表的操作
头文件
#include<conio.h>
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>
结构体定义
#define LEN sizeof(LNode) //定义LEN为一个结点的长度
typedef enum
{
False = 0,
True = 1,
} BOOL; //定义BOOL型
typedef struct node
{
char date; //数据域
struct node* next; //嵌套定义 指向下一个结点的指针
}LNode,*LinkList;
函数声明
void CreatList(LinkList&, int);
BOOL ListInsert(LinkList&, int,char);
BOOL ListDelete(LinkList&,int,char &);
BOOL ListFind_keyword(LinkList,char ,int &);
BOOL ListFind_order(LinkList, char &, int);
void ListPrint(LinkList);
主函数
int main()
{
LinkList L;
BOOL temp;
int num, loc=0, flag = 1,j;
char ch,h;
printf("本程序实现链式结构的线性表操作。\n");
printf("可进行插入,删除,定位,查找等操作。\n");
printf("请输入初始时链表的长度:"); //输入生成单链表时的元素个数
scanf("%d", &num);
CreatList(L, num); //生成单链表
ListPrint(L);
while (flag)
{
printf("\n请选择需要进行的操作\n");
printf("1.显示所有元素\n");
printf("2.插入一个元素\n");
printf("3.删除一个元素\n");
printf("4.按关键字查找元素\n");
printf("5.按序号查找元素\n");
printf("6.退出程序\n");
scanf("%d", &j);
switch (j)
{
case 1:ListPrint(L);break;
case 2:
{printf("请输入要插入的位置:\n");
scanf("%d", &loc);
scanf("%c", &h); //如果不加这行吸收回车键,则输入位置后的回车会被存入ch中,导致结果错误
printf("请输入元素(一个字符)\n");
scanf("%c", &ch);
temp = ListInsert(L, loc, ch); //执行插入元素的操作
if (temp == False)
printf("插入失败\n");
else
printf("插入成功\n");
ListPrint(L);}
break;
case 3: {printf("请输入要删除的元素所在位置");
scanf("%d", &loc);
temp = ListDelete(L, loc, ch); //执行删除元素的操作
if (temp == False)
printf("删除失败!\n");
else
printf("成功删除了值为%c的元素", ch);
ListPrint(L);}
break;
case 4: {if (L->next == NULL)
printf("链表为空\n");
else
{
printf("请输入要查找的元素(一个字符):");
scanf("%c%c", &h, &ch); //输入j后的回车会被存入ch,故需要一个额外的h来吸收掉回车
temp = ListFind_keyword(L, ch, loc); //执行按关键字查找元素的操作
if (temp == False)
printf("没有找到该元素!\n");
else
printf("该元素在链表的第%d个位置。\n", loc);
}}
break;
case 5: {if (L->next == NULL)
printf("链表为空!\n");
else
{
printf("请输入要查找的位置:");
scanf("%d", &loc);
temp = ListFind_order(L, ch, loc); //执行按序号查找元素的操作
if (temp == False)
printf("该位置不存在!\n");
else
printf("第%d个元素是:%c\n", loc, ch);
}}
break;
default: {flag = 0;printf("程序结束,按任意键退出!\n");}
break;
}
}
}
生成一个带头结点的有n个元素的单链表
void CreatList(LinkList& v, int n)
{
int i;
LinkList p;
v = (LinkList)malloc(LEN); //生成头结点
v->next = NULL;
printf("请输入%d个字符,例如:abcdefg\n", n);
for (i = n;i >0 ;i--) //采用头插法,故而现输入反而在后面结点
{
p = (LinkList)malloc(LEN); //生成新结点
scanf(" %c", &p->date);
p->next = v->next; //勾链从右往左进行
v->next = p;
}
char h;//因为输入之后的回车键会影响之后的输入故而在此消耗掉回车
scanf_s("%c", &h);
}
在单链表的第i个位置插入e
BOOL ListInsert(LinkList& v, int i, char e)
{
LinkList p, s;
int j = 0;
p = v;
while (p && j < i - 1) //当p结点不为空且插入位置在表内时进行循环
{
p = p->next; //p结点依次后移。同时j作为位置计数也不断后移
++j; //结束时p指向第i-1个位置
}
if (!p || j > i - 1)
return False; //没有找到该位置
s = (LinkList)malloc(LEN); //生成新结点
s->date = e;
s->next = p->next; //将新结点插入到单链表中,即修改指针,完成插入操作
p->next = s;
return True;
}
在单链表中删除第i个元素
BOOL ListDelete(LinkList& v, int i, char& e)
{
LinkList p, q;
int j = 0;
p = v;
while (p->next && j < i - 1)
{
p = p->next;
++j; //结束时p指向第i-1个位置
}
if (!(p->next) || j > i - 1)
return False;
q = p->next; //此处小心p q输入错误
p->next = q->next;
e = q->date; //e取得该元素的值,即修改指针删除结点p
free(q);
return True;
}
在单链表中查找关键字为e的元素
BOOL ListFind_keyword(LinkList v, char e, int &i)
{
i = 1;
LinkList p;
p = v->next;
while ((p->date != e) && (p->next != NULL))
{
p = p->next;
i++; //循环结束后i的值就是值为e的结点的位置
}
if (p->date != e)
return False;
else
return True;
}
在单链表中查找第i个元素
BOOL ListFind_order(LinkList v, char& e, int i)
{
LinkList p;
int j = 0;
p = v;
while (p->next && j < i)
{
p = p->next;
++j; //循环结束时j==i
}
if (j != i)
return False;
e = p->date;
return True;
}
显示链表所有元素
void ListPrint(LinkList v)
{
LinkList q;
q = v->next;
printf("链表所有元素:");
while (q != NULL)
{
printf("%c ", q->date);
q = q->next;
}
printf("\n");
}
运行结果