数据结构 单链表各种运算的实现
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
char data;
struct LNode * next;
}LinkList;
void InitList(LinkList *&L) //初始化,建立一个空的单链表
{
L = (LinkList *)malloc(sizeof(LinkList));
L->next = NULL; //创建头节点,其next域置为NULL
}
void DispList(LinkList *L) //输出线性表
{
LinkList *p = L->next; //p指向开始节点
while (p != NULL) //p不为NULL,输出*p节点的data域
{
printf("%3c", p->data);
p = p->next; //p移向下一个节点
}
printf("\n\n");
}
int ListLength(LinkList *L) //求线性表的长度
{
int n = 0;
LinkList *p = L; //p指向头节点,n置为0(即头节点的序号为0)
while (p->next != NULL)
{
n++;
p = p->next;
}
return n; //循环结束,p指向尾节点,其序号n为节点个数
}
bool ListEmpty(LinkList *L) //判断是否为空表
{
return (L->next != NULL); //若单链表L没有数据节点,则返回真,否则返回假
}
bool GetElem(LinkList *L, int i, char &e) //求线性表中某个数据元素值
{
int j = 0;
LinkList *p = L; //p指向头节点,j置为0(即头节点的序号为0)
while (j<i&&p != NULL) //找第i个节点
{
j++;
p = p->next;
}
if (p == NULL) //不存在第i个数据节点,返回false
return false;
else //存在第i个数据节点,返回true
{
e = p->data;
return true;
}
}
int LocateElem(LinkList *L, char e) //按元素值查找节点
{
int i = 1;
LinkList *p = L->next; //p指向开始节点,i置为1(即开始节点的序号为1)
while (p != NULL && p->data != e) //查找data值为e的节点,其序号为i
{
p = p->next;
i++;
}
if (p == NULL) //不存在元素值为e的节点,返回0
return 0;
else //存在元素值为e的节点,返回其逻辑序号i
return i;
}
bool ListInsert(LinkList *&L, int i, char e) //插入数据元素
{
int j = 0;
LinkList *p = L, *s; //p指向头节点,j置为0
while (j<i - 1 && p != NULL) //查找第i-1个节点
{
j++;
p = p->next;
}
if (p == NULL) //未找到第i-1个节点,返回false
return false;
else //找到第i-1个节点*p,插入新节点并返回true
{
s = (LinkList*)malloc(sizeof(LinkList));
s->data = e; //创建新节点*e,其data域置为e
s->next = p->next; //将*s插入到*p之后
p->next = s;
return true;
}
}
bool ListDelete(LinkList *&L, int i, char &e) //删除数据元素
{
int j = 0;
LinkList *p = L, *q; //p指向头节点,j置为0(即头节点的序号为0)
while (j<i - 1 && p != NULL) //查找第i-1个节点
{
j++;
p = p->next;
}
if (p == NULL) //未找到第i-1个节点,返回false
return false;
else //找到第i-1个节点*p
{
q = p->next; //q指向第i个节点
if (q == NULL) //若不存在第i个节点,返回false
return false;
e = q->data;
p->next = q->next; //从单链表中删除*q节点
free(q); //释放*q节点
return true; //返回true表示成功删除第i个节点
}
}
void DestroyList(LinkList *&L) //销毁单链表L
{
LinkList *pre = L, *p = L->next; //pre指向*p的前驱节点
while (p != NULL) //扫描单链表L
{ free(pre); //释放*pre节点
pre = p; //pre、pre同步后移一个节点
p = pre->next;
}
free(pre); //循环结束时,p为NULL,pre指向尾节点,释放它
}
int main()
{
LinkList *h;
char e;
int i;
InitList(h);
printf("\n创建一个空的单链表\n使用尾差法插入a,b,c,d,e \n");
ListInsert(h, 1, 'a');
ListInsert(h, 2, 'b');
ListInsert(h, 3, 'c');
ListInsert(h, 4, 'd');
ListInsert(h, 5, 'e');
printf(" 输出单链表h:\n");
DispList(h);
i = ListLength(h);
printf("单链表h的长度为:%3d\n\n", i);
if (ListEmpty(h) == 0)
printf("单链表为空\n\n");
else
printf("单链表不为空\n\n");
GetElem(h, 3, e);
printf("单链表第三个元素为:%3c\n\n", e);
i = LocateElem(h, 'a');
printf("a的位置为%3d\n\n", i);
printf("在第四个位置插入f\n");
ListInsert(h, 4, 'f');
printf("插入后单链表h为:\n");
DispList(h);
printf("删除第三个元素\n");
ListDelete(h, 3, e);
printf(" 删除后单链表h为:\n");
DispList(h);
DestroyList(h);
printf("单链表h已释放 \n\n");
return 0;
}