- 循环表
一、定义:最后一个结点的 next 域指向头结点处
二、结构:
typedef struct CNode
{
int data;
struct CNode *next;
}CNode,*CList;
三、基本操作
1>初始化单链表
void InitList(CList plist)
{
assert(plist!=NULL);
plist->next=plist;
}
2>得到一个结点
CNode *GetCNode(int val)
{
CNode *cnode=(CNode *)malloc(sizeof(CNode));
assert(cnode!=NULL);
cnode->next=NULL;
cnode->data=val;
return cnode;
}
3>头插法
bool Insert_head(CList plist,int val)
{
assert(plist!=NULL&&plist->next !=NULL);
CNode *cnode=GetCNode(val);
if(cnode!=NULL)
{
cnode->next=plist->next;
plist->next=cnode;
return true;
}
return false;
}
3>尾插法
bool Insert_tail(CList plist,int val)
{
assert(plist!=NULL&&plist->next !=NULL);
CNode *cur=plist;
while(cur->next!=plist)
{
cur=cur->next;
}
CNode *cnode=GetCNode(val);
if(cnode!=NULL)
{
cur->next=cnode;
cnode->next=plist;
}
return true;
}
4>查找前驱
CNode *Search_pri(CList plist,int key)
{
assert(plist!=NULL&&plist->next !=NULL);
CNode *cur=plist;
while(cur->next!=plist)(要在注意循环结束条件与单链表的不同)
{
if(cur->next->data==key)
{
return cur;
}
cur=cur->next ;
}
return NULL;
}
4>删除值为key的结点
bool Delete(CList plist,int key)
{
assert(plist!=NULL&&plist->next !=NULL);
CNode *cur=Search_pri(plist,key);//找到其前驱结点
CNode *pDel=cur->next;//pDel是要删除的结点
if(cur!=NULL)
{
cur->next=pDel->next;
return true;
}
return false;
}
5>判断循环单链表是否为空
bool IsEmpty(CList plist)//是否为空
{
return plist->next==plist;
}
6>摧毁单链表
void Destroy(CList plist)//摧毁
{
CList p=NULL;
while(plist->next!=plist)
{
p=plist->next;//一个一个进行摧毁
plist->next=p->next;
free(p);
}
p=NULL;
}
7>得到循环单链表的长度
int GetLength(CList plist)//得到长度
{
CList p=plist;
int len=0;
while(p->next!=plist)
{
len++;
}
return len;
}
8>显示函数
void Show(CList plist)
{
CList p=plist->next;
while(p!=plist)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
- 双向链表
一、定义:对于循环单链表来说,它的每个数据结点中都有两个指针,分别
指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,
都可以很方便地访问它的前驱结点和后继结点。
二、结构
typedef struct DNode
{
int data;
struct DNode *next;
struct DNode *prio;
}DNode,*DList;
三、基本操作
1>初始化双向链表
void InitList(DList plist)
{
assert(plist!=NULL);
plist->prev=NULL;
plist->next=NULL;
}
2>创建一个结点
static DNode *pGetnode(int val)
{
DNode *pGet=(DNode *)malloc(sizeof(DNode));
assert(pGet!=NULL);
pGet->data=val;
pGet->next=NULL;
pGet->prev=NULL;
return pGet;
}
3>头插法
bool Insert_head(DList plist,int val)
{
assert(plist!=NULL);
DNode *pGet=pGetnode(val);
pGet->next=plist->next;
if(pGet->next !=NULL)//()
{
pGet->next->prev=pGet;
}
plist->next=pGet;
pGet->prev=plist;
return true;
}
4>尾插法
bool Insert_tail(DList plist,int val)
{
DNode *pGet=pGetnode(val);
assert(pGet!=NULL);
DNode *p=plist;
while(p->next !=NULL)
{
p=p->next;
}
p->next =pGet;
pGet->prev =pGet;
return true;
}
5>查找值为key的结点
DNode *Search_pri(DList plist,int key)//找key的前驱
{
assert(plist!=NULL);
DNode *p=plist;
while(p->next!=NULL)
{
if(p->next->data==key)
{
return p;
}
p=p->next;
}
return NULL;
}
6>删除值为key的结点
bool Delete(DList plist,int key)//删值为key的结点
{
assert(plist!=NULL);
DNode *p=Search_pri(plist,key);//p为key的前驱
if(p!=NULL)
{
DNode * pDel=p->next;//pDel->data==key
p->next=pDel->next;
if(pDel->next!=NULL)
{
pDel->next->prev=p;
}
free(pDel);
pDel=NULL;
return true;
}
return false;
}
7>判断是否为空
bool IsEmpty(DList plist)
{
return plist->next==NULL;
}
8>摧毁函数
void Destroy(DList plist)
{
DNode *p=NULL;
while(plist->next!=NULL)
{
p=plist->next;
plist->next=p->next;
free(p);
}
p=NULL;
}
9>双向链表的长度
int GetLength(DList plist)
{
assert(plist!=NULL);
int len=0;
DList p=plist;
while(p->next!=NULL)
{
len++;
p=p->next ;
}
return len;
}
10>打印函数
void Show(DList plist)
{
DNode *p=plist->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}