由于顺序表中的每个元素至多只有一个前驱元素和一个后继元素,即数据元素之间是一对一的逻辑关系,所以当进行链式存储时,一种最简单最常用的方法是:
在每一个结点中除包含有包含数据域外,只设置一个指针域,用以指向其后继结点,这样构成的链接表称为线性单向链接表,简称单链表。
单链表中结点类型描述为:
#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef struct LNode //定义单链表节点类型
{
ElemType data; //存放元素值
struct LNode *next; //指向后继节点
}LinkList;
单链表中基本操作为:
先进行对基本函数的声明,然后在主函数中进行调用:
void InitList(LinkList *&L);
void createlist(LinkList *&L);
bool ListInsert(LinkList *&L,int i,ElemType e);
void DispList(LinkList *L);
int ListLength(LinkList *L);
bool ListEmpty(LinkList *L);
bool GetElem(LinkList *L,int i,ElemType &e);
int LocateElem(LinkList *L,ElemType e);
bool ListDelete(LinkList *&L,int i,ElemType &e);
void DestroyList(LinkList *&L);
int main()
{
LinkList *L;
ElemType e;
//初始化顺序表
InitList(L);
//建立单链表,应用头插法
createlist(L);
//输出顺序表
DispList(L);
//输出顺序表的长度
printf("%d\n",ListLength(L));
//判断该顺序表是否为空
if(ListEmpty(L)==false) printf("该顺序表不为空\n");
else printf("该顺序表为空\n");
//对某个元素进行输出
if(GetElem(L,3,e)==1) printf("%c\n",e);
else printf("该元素不存在\n");
printf("%d\n",LocateElem(L,'a'));
ListInsert(L,0,'f'); DispList(L);
ListDelete(L,1,e); DispList(L);
printf("%d\n",ListLength(L));
DestroyList(L);
return 0;
}
初始化单链表
//初始化单链表(创建一个空的单链表)
void InitList(LinkList *&L)
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL; //创建头节点,其next域置为NULL
}
建立单链表,在这里我们可以运用头插法或尾插法进行建立,下面我们运用的是尾插法进行单链表的建立
//尾插法建立单链表
void createlist(LinkList *&L)
{
ElemType k;
LinkList *r,*s;
L=(LinkList *)malloc(sizeof(LinkList));
r=L;
r->next=NULL;
while(1)
{
scanf("%c",&k);
if(k=='z')
break;
s=(LinkList *)malloc(sizeof(LinkList));
s->data=k;
s->next=r->next;
r->next=s;
r=s;
}
}
单链表进行元素的插入操作
//依次插入元素(尾插法)
bool ListInsert(LinkList *&L,int i,ElemType e)
{
int j=0;
LinkList *p=L,*s; //p指向头节点,j置为0(即头节点的序号为0)
while(j<i-1 && p!=NULL) //查找第i-1个节点
{
j++;
p=p->next;
}
if(j!=i-1) //未找到第i-1个节点,(指i过大或i过小为0)返回false
{
printf("i过大或i过小为0");
return false;
}
else //找到第i-1个节点*p,插入新节点并返回true
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data=e; //创建新节点*s,其data域置为e
s->next=p->next; //将*s插入到*p之后
p->next=s;
return true;
}
}
删除操作
//删除L中的元素
bool ListDelete(LinkList *&L,int i,ElemType &e)
{
int j=0;
LinkList *p=L,*q;
while(j<i-1 && p!=NULL)
{
j++;
p=p->next;
}
if(j!=i-1)
{
printf("i过大或i为0!\n");
return false;
}
else
{
q=p->next;
if(q==NULL)
return false;
e=q->data;
p->next=q->next;
free(q);
return true;
}
}
按序号查找,即取单链表中第i个元素
//输出单链表中某个数据元素值
bool GetElem(LinkList *L,int i,ElemType &e)
{
int j=0;
LinkList *p=L;
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
if(j!=i)
return false;
else
{
e=p->data;
return true;
}
}
按元素值查找,即输出该元素在单链表中的位置
//按元素值查找
int LocateElem(LinkList *L,ElemType e)
{
int i=1;
LinkList *p=L->next;
while(p!=NULL && p->data!=e)
{
p=p->next;
i++;
}
if(p->data==e)
return(i);
else
{
printf("该元素不存在!\n");
return 0;
}
}
//输出单链表
void DispList(LinkList *L)
{
LinkList *p=L->next;
while(p!=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
//输出单链表h的长度
int ListLength(LinkList *L)
{
int n=0;
LinkList *p=L;
while(p->next!=NULL)
{
n++;
p=p->next;
}
return(n);
}
//判断单链表是否为空表(空为真,非空为假)
bool ListEmpty(LinkList *L)
{
return (L->next==NULL);
}
//销毁单链表
void DestroyList(LinkList *&L)
{
LinkList *pre=L,*p=L->next;
while(p!=NULL)
{
free(pre);
pre=p;
p=pre->next;
}
free(pre);
}