循环链表(转自WIKI)

循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。

]单向循环链表

存储结构和单链表相同。

/*  设立尾指针的单循环链表的12个基本操作  */
void  InitList(LinkList  * L)
/*  操作结果:构造一个空的线性表L  */
  
* L = (LinkList)malloc( sizeof ( struct  LNode));  /*  产生头结点,并使L指向此头结点  */
  
if ( !* L)  /*  存储分配失败  */
    exit(OVERFLOW);
  (
* 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;
}


void  ClearList(LinkList  * L)  /*  改变L  */
/*  初始条件:线性表L已存在。操作结果:将L重置为空表  */
  LinkList p,q;
  
* L = ( * L) -> next;  /*  L指向头结点  */
  p
= ( * L) -> next;  /*  p指向第一个结点  */
  
while (p !=* L)  /*  没到表尾  */
  {
    q
= p -> next;
    free(p);
    p
= q;
  }
  (
* L) -> next =* L;  /*  头结点指针域指向自身  */
}

 

Status ListEmpty(LinkList L)
/*  初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE  */
  
if (L -> next == L)  /*  空  */
    
return  TRUE;
  
else
    
return  FALSE;
}

 

int  ListLength(LinkList L)
/*  初始条件:L已存在。操作结果:返回L中数据元素个数  */
  
int  i = 0 ;
  LinkList p
= L -> next;  /*  p指向头结点  */
  
while (p != L)  /*  没到表尾  */
  {
    i
++ ;
    p
= p -> next;
  }
  
return  i;
}


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;
}


int  LocateElem(LinkList L,ElemType e,Status( * compare)(ElemType,ElemType))
/*  初始条件:线性表L已存在,compare()是数据元素判定函数  */
  
/*  操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
  
/*            若这样的数据元素不存在,则返回值为0  */
  
int  i = 0 ;
  LinkList p
= L -> next -> next;  /*  p指向第一个结点  */
  
while (p != L -> next)
  {
    i
++ ;
    
if (compare(p -> data,e))  /*  满足关系  */
      
return  i;
    p
= p -> next;
  }
  
return   0 ;
}


Status PriorElem(LinkList L,ElemType cur_e,ElemType  * pre_e)
/*  初始条件:线性表L已存在  */
  
/*  操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
  
/*            否则操作失败,pre_e无定义  */
  LinkList q,p
= L -> next -> next;  /*  p指向第一个结点  */
  q
= p -> next;
  
while (q != L -> next)  /*  p没到表尾  */
  {
    
if (q -> data == cur_e)
    {
      
* pre_e = p -> data;
      
return  TRUE;
    }
    p
= q;
    q
= q -> next;
  }
  
return  FALSE;  /*  操作失败  */
}

 

Status NextElem(LinkList L,ElemType cur_e,ElemType  * next_e)
/*  初始条件:线性表L已存在  */
  
/*  操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
  
/*            否则操作失败,next_e无定义  */
  LinkList p
= L -> next -> next;  /*  p指向第一个结点  */
  
while (p != L)  /*  p没到表尾  */
  {
    
if (p -> data == cur_e)
    {
      
* next_e = p -> next -> data;
      
return  TRUE;
    }
    p
= p -> next;
  }
  
return  FALSE;  /*  操作失败  */
}

 

Status ListInsert(LinkList  * L, int  i,ElemType e)  /*  改变L  */
/*  在L的第i个位置之前插入元素e  */
  LinkList p
= ( * L) -> next,s;  /*  p指向头结点  */
  
int  j = 0 ;
  
if (i <= 0 || i > ListLength( * L) + 1 /*  无法在第i个元素之前插入  */
    
return  ERROR;
  
while (j <  i - 1 /*  寻找第i-1个结点  */
  {
    p
= p -> next;
    j
++ ;
  }
  s
= (LinkList)malloc( sizeof ( struct  LNode));  /*  生成新结点  */
  s
-> data = e;  /*  插入L中  */
  s
-> next = p -> next;
  p
-> next = s;
  
if (p ==* L)  /*  改变尾结点  */
    
* L = s;
  
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)  /*  删除的是表尾元素  */
    
* L = p;
  free(q); 
/*  释放待删除结点  */
  
return  OK;
}

 

void  ListTraverse(LinkList L, void ( * vi)(ElemType))
/*  初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()  */
  LinkList p
= L -> next -> next;  /*  p指向首元结点  */
  
while (p != L -> next)  /*  p不指向头结点  */
  {
    vi(p
-> data);
    p
= p -> next;
  }
  printf(
" \n " );


 

你可能感兴趣的:(链表)