循环链表基本操作
处理好地址的关系,&, * ,**,不知道是无法了解这个算法的。
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode;
typedef struct LNode *LinkList;
void InitList(LinkList *L)
{
*L=(LinkList*)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点
if(!L) // 存储分配失败
return 0;
(*L)->next=(*L); // 指针域指向头结点 //这么就形成循环链表了
}
Status ListEmpty(LinkList L)
{
// 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE;否则返回FALSE
if(L->next==L) // 空
return 1;
else
return 0;
}
int ListLength(LinkList L)
{
// 初始条件: L已存在。操作结果:返回L中数据元素个数
int i=0;
LinkList p=L->next; // p指向头结点
while(p!=L) // 没到表尾
{
i++;
p=p->next;
}
return i;
}
Status ListInsert(LinkList *L,int i,ElemType e) // 改变L
{
// 在L的第i个位置之前插入元素e
LinkList p=(*L)->next,s; // p指向头结点
int j=0;
while(j<i-1) // 寻找第i-1个结点
{
p=p->next;
j++;
}
s=(LinkList)malloc(sizeof(LNode)); // 生成新结点
s->data=e; // 插入L中
s->next=p->next;
p->next=s;
if(p==(*L)) // 改变尾结点
(*L)=s;
return OK;
}
void ListTraverse(LinkList L)
{
// 初始条件: L已存在
// 操作结果:依次对L的每个数据元素调用函数vi()
LinkList p=L->next->next; // p指向首元结点
while(p!=L->next) // p不指向头结点
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
Status GetElem(LinkList L,int i,ElemType *e)
{
// 当第i个元素存在时,其值赋给e并返回OK;否则返回ERROR
int j=1; // 初始化, j为计数器
LinkList p=L->next->next; // p指向第一个结点
if(i<=0||i>ListLength(L)) // 第i个元素不存在
return ERROR;
while(j<i)
{
// 顺指针向后查找,直到p指向第i个元素
p=p->next;
j++;
}
*e=p->data; // 取第i个元素
return OK;
}
Status ListDelete(LinkList *L,int i,ElemType *e)
// 改变L
{
// 删除L的第i个元素,并由e返回其值
LinkList p=(*L)->next,q; // p指向头结点
int j=0;
if(i<=0||i>ListLength(*L)) // 第i个元素不存在
return ERROR;
while(j<i-1) // 寻找第i-1个结点
{
p=p->next;
j++;
}
q=p->next; // q指向待删除结点
p->next=q->next;
e=q->data;
if((*L)==q) // 删除的是表尾元素(见图235)
(*L)=p;
free(q); // 释放待删除结点
return OK;
}
void ClearList(LinkList *L) // 改变L
{
// 初始条件:线性表L已存在。操作结果:将L重置为空表(见图232)
LinkList p,q;
(*L)=(*L)->next; // L指向头结点
p=(*L)->next; // p指向第一个结点
while(p!=(*L)) // 没到表尾
{
q=p->next;
free(p);
p=q;
}
(*L)->next=(*L); // 头结点指针域指向自身
}
void DestroyList(LinkList *L)
{
// 操作结果:销毁线性表L
LinkList q,p=(*L)->next; // p指向头结点
while(p!=(*L)) // 没到表尾
{
q=p->next;
free(p);
p=q;
}
free(*L);
*L=NULL;
}
int main()
{
LinkList L; //这个是地址了已经
ElemType e;
int j;
Status i;
InitList(&L); // 初始化单循环链表L
// L=(LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点
// if(!L) // 存储分配失败
// return 0;
//L->next=L; // 指针域指向头结点 //这么就形成循环链表了
i=ListEmpty(L);
printf("L是否空 i=%d(1:空 0:否)\n",i);
j=ListLength(L);
printf("L中数据元素个数=%d\n",j);
ListInsert(&L,1,3); // 在L中依次插入3,5
ListInsert(&L,2,5); // 在L中依次插入3,5
ListInsert(&L,3,7); // 在L中依次插入3,5
ListTraverse(L);
GetElem(L,2,&e);
printf("第2个元素是%d\n",e);
i=ListDelete(&L,2,&e);
ListTraverse(L);
ClearList(&L);
printf("清空L后, L是否空: %d(1:空 0:否)\n",ListEmpty(L));
DestroyList(&L);
return 0;
}