目录
单链表实现
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。因此,为了表示每个数据元素ai与其直接后继数据元素a(i+1)之间的逻辑关系,对数据元素ai来说,除了存储本身的信息之外,还需要存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素ai的存储映像,称为结点。结点包括两个域:其中存储数据元素信息的域称之为数据域;存储直接后继存储位置的域称为指针域。如图1所示:
指针域中存储的信息称作指针或链,n个结点链结成一个链表,即单链表,(a1,a2,a3,......,an)。如图2所示:
单链表实现:
基本操作:
//构造一个空的线性表L
Status InitList(CList &L);
//销毁线性表L
Status DestroyList(CList &L);
//将L重置为空表
Status ClearList(CList &L);
//若L为空表,则返回TRUE,否则返回FALSE;
Status ListEmpty(CList L);
//用e返回L中第i个数据元素的值
Status GetElem(CList L,int i,LElemType &e);
//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义
Status PriorElem(CList L,LElemType cur_e,LElemType &pre_e);
//若cur_e是L中的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
Status nextElem(CList L,LElemType cur_e,LElemType &next_e);
//依次对L的每个数据元素调用函数visit().一旦visit()失败,则操作失败
Status ListTraverse(CList L,Status (*visit)(LElemType e));
代码实现:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
enum Status{OK = 1,ERROR = 0,TRUE = 1,FALSE = 0,OVERFLOW = -1};
typedef int LElemType;
typedef struct Node //定义结点类型
{
LElemType data; //数据域
struct Node *next; //结点域
}pNode;
typedef struct list
{
pNode *head;
}CList;
//构造一个空的线性表L
Status InitList(CList &L)
{
L.head = (pNode*)malloc(sizeof(pNode)); //动态开辟结点空间
if(NULL == L.head)
exit(OVERFLOW); //开辟失败,返回
L.head->next = NULL;
return OK;
}
//销毁线性表L
Status DestroyList(CList &L)
{
pNode *pcur = L.head;
while(pcur != NULL)
{
L.head = L.head->next;
free(pcur);
pcur = L.head;
}
return OK;
}
//将L重置为空表
Status ClearList(CList &L)
{
pNode *pcur = L.head->next;
while(pcur != NULL)
{
L.head->next = pcur->next;
free(pcur);
pcur = L.head->next;
}
return OK;
}
//若L为空表,则返回TRUE,否则返回FALSE;
Status ListEmpty(CList L)
{
if(L.head->next == NULL)
return FALSE;
else
return TRUE;
}
//返回L中数据元素个数
int ListLength(CList L)
{
int count = 0; //定义一个计数器
pNode *pcur = L.head->next;
while(pcur != NULL)
{
count++;
pcur = pcur->next;
}
return count;
}
//用e返回L中第i个数据元素的值
Status GetElem(CList L,int i,LElemType &e)
{
if(i <= 0 || i >= ListLength(L))
return ERROR;
int count = 0; //定义一个计数器
pNode *pcur = L.head->next;
while(pcur != NULL)
{
count++;
if(count == i)
{
e = pcur->data;
return TRUE;
}
pcur = pcur->next;
}
return FALSE;
}
//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义
Status PriorElem(CList L,LElemType cur_e,LElemType &pre_e)
{
pNode *pre = L.head;
pNode *pcur = L.head->next;
if(pcur->data == cur_e)
return ERROR; //如果是第一个节点,返回
else
{
pre = pre->next;
pcur = pcur->next;
}
while(pcur != NULL)
{
if(pcur->data == cur_e)
{
pre_e = pre->data;
return OK;
}
pre = pre->next;
pcur = pcur->next;
}
return ERROR;
}
//获取元素
pNode* GetNode(LElemType e)
{
pNode *pGet = (pNode*)malloc(sizeof(pNode));
if(NULL == pGet)
exit(OVERFLOW);
pGet->data = e;
pGet->next = NULL;
return pGet;
}
//在L中第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert(CList &L,int i,LElemType e)
{
if(i < 0 || i > (ListLength(L) + 1))
return ERROR;
int count = 0; //定义一个计数器
pNode *pcur = L.head->next;
pNode *pre = L.head;
if(ListLength(L) == 0)
{
pNode *pGet = GetNode(e);
L.head->next = pGet;
return OK;
}
while(pcur != NULL)
{
count++;
if(count == i)
{
pNode *pGet = GetNode(e);
pGet->next = pre->next;
pre->next = pGet;
return OK;
}
pcur = pcur->next;
pre = pre->next;
}
return ERROR;
}
//若cur_e是L中的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
Status nextElem(CList L,LElemType cur_e,LElemType &next_e)
{
pNode *pcur = L.head->next;
pNode *pnext = L.head->next->next;
while(pcur != NULL)
{
if(pnext->next == NULL)
return ERROR; //说明此时已经搜寻到倒数第一个了
if(pcur->data == cur_e)
{
next_e = pnext->data;
return OK;
}
pcur = pcur->next;
pnext = pnext->next;
}
return ERROR;
}
//定义visit()
Status PrintfElement(LElemType e)
{
printf("%d ",e);
return OK;
}
//依次对L的每个数据元素调用函数visit().一旦visit()失败,则操作失败
Status ListTraverse(CList L,Status (*visit)(LElemType e))
{
pNode *pcur = L.head->next;
while(pcur != NULL)
{
(*visit)(pcur->data);
pcur = pcur->next;
}
printf("\n");
return OK;
}
main函数:
int main()
{
CList list;
int e = 0;
InitList(list);
ListInsert(list,1,2);
ListInsert(list,1,5);
ListInsert(list,1,8);
ListInsert(list,1,11);
ListInsert(list,1,15);
ListTraverse(list,PrintfElement);
GetElem(list,3,e);
printf("elem = %d\n",e);
PriorElem(list,11,e);
printf("pre_e = %d\n",e);
nextElem(list,8,e);
printf("next_e = %d\n",e);
printf("len = %d\n",ListLength(list));
ClearList(list);
printf("len = %d\n",ListLength(list));
DestroyList(list);
return 0;
}