fbpx
维基百科

循环链表

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

单向循环链表 编辑

存储结构 编辑

/* c2-2.h 线性表的单链表存储结构 */ typedef struct LNode {  ElemType data;  struct LNode *next; }LNode,*LinkList; 

基本操作 编辑

/* bo2-4.c 设立尾指针的单循环链表(存储结构由c2-2.h定义)的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"); } 

[1]

双向循环链表 编辑

循环链表的应用问题 编辑

Josephu问题:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人找到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。 如何用循环链表来求解Josephu问题?

参考文献 编辑

  1. ^ 高一凡. 《数据结构》算法实现及解析 2004年10月第2版. 西安: 西安电子科技大学出版社. ISBN 9787560611761 (中文). 

循环链表, 是一种链式存储结构, 它的最后一个结点指向头结点, 形成一个环, 因此, 从中的任何一个结点出发都能找到任何其他结点, 的操作和单链表的操作基本一致, 差别仅仅在于算法中的循环条件有所不同, 目录, 单向, 存储结构, 基本操作, 双向, 的应用问题, 参考文献单向, 编辑存储结构, 编辑, 线性表的单链表存储结构, typedef, struct, lnode, elemtype, data, struct, lnode, next, lnode, linklist, 基本操作, 编辑, 设立尾指针的. 循环链表是一种链式存储结构 它的最后一个结点指向头结点 形成一个环 因此 从循环链表中的任何一个结点出发都能找到任何其他结点 循环链表的操作和单链表的操作基本一致 差别仅仅在于算法中的循环条件有所不同 目录 1 单向循环链表 1 1 存储结构 1 2 基本操作 2 双向循环链表 3 循环链表的应用问题 4 参考文献单向循环链表 编辑存储结构 编辑 c2 2 h 线性表的单链表存储结构 typedef struct LNode ElemType data struct LNode next LNode LinkList 基本操作 编辑 bo2 4 c 设立尾指针的单循环链表 存储结构由c2 2 h定义 的12个基本操作 void InitList LinkList L 操作结果 构造一个空的线性表L L LinkList malloc sizeof struct LNode 产生头结点 并使L指向此头结点 if L 存储分配失败 exit OVERFLOW L gt next L 指针域指向头结点 void DestroyList LinkList L 操作结果 销毁线性表L LinkList q p L gt next p指向头结点 while p L 没到表尾 q p gt next free p p q free L L NULL void ClearList LinkList L 改变L 初始条件 线性表L已存在 操作结果 将L重置为空表 LinkList p q L L gt next L指向头结点 p L gt next p指向第一个结点 while p L 没到表尾 q p gt next free p p q L gt next L 头结点指针域指向自身 Status ListEmpty LinkList L 初始条件 线性表L已存在 操作结果 若L为空表 则返回TRUE 否则返回FALSE if L gt next L 空 return TRUE else return FALSE int ListLength LinkList L 初始条件 L已存在 操作结果 返回L中数据元素个数 int i 0 LinkList p L gt next p指向头结点 while p L 没到表尾 i p p gt next return i Status GetElem LinkList L int i ElemType e 当第i个元素存在时 其值赋给e并返回OK 否则返回ERROR int j 1 初始化 j为计数器 LinkList p L gt next gt next p指向第一个结点 if i lt 0 i gt ListLength L 第i个元素不存在 return ERROR while j lt i 顺指针向后查找 直到p指向第i个元素 p p gt next j e p gt 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 gt next gt next p指向第一个结点 while p L gt next i if compare p gt data e 满足关系 return i p p gt 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 gt next gt next p指向第一个结点 q p gt next while q L gt next p没到表尾 if q gt data cur e pre e p gt data return TRUE p q q q gt next return FALSE 操作失败 Status NextElem LinkList L ElemType cur e ElemType next e 初始条件 线性表L已存在 操作结果 若cur e是L的数据元素 且不是最后一个 则用next e返回它的后继 否则操作失败 next e无定义 LinkList p L gt next gt next p指向第一个结点 while p L p没到表尾 if p gt data cur e next e p gt next gt data return TRUE p p gt next return FALSE 操作失败 Status ListInsert LinkList L int i ElemType e 改变L 在L的第i个位置之前插入元素e LinkList p L gt next s p指向头结点 int j 0 if i lt 0 i gt ListLength L 1 无法在第i个元素之前插入 return ERROR while j lt i 1 寻找第i 1个结点 p p gt next j s LinkList malloc sizeof struct LNode 生成新结点 s gt data e 插入L中 s gt next p gt next p gt next s if p L 改变尾结点 L s return OK Status ListDelete LinkList L int i ElemType e 改变L 删除L的第i个元素 并由e返回其值 LinkList p L gt next q p指向头结点 int j 0 if i lt 0 i gt ListLength L 第i个元素不存在 return ERROR while j lt i 1 寻找第i 1个结点 p p gt next j q p gt next q指向待删除结点 p gt next q gt next e q gt data if L q 删除的是表尾元素 L p free q 释放待删除结点 return OK void ListTraverse LinkList L void vi ElemType 初始条件 L已存在 操作结果 依次对L的每个数据元素调用函数vi LinkList p L gt next gt next p指向首元结点 while p L gt next p不指向头结点 vi p gt data p p gt next printf n 1 双向循环链表 编辑参见 双链表循环链表的应用问题 编辑主条目 约瑟夫问题 Josephu问题 据说著名犹太历史学家 Josephus有过以下的故事 在罗马人占领乔塔帕特后 39 个犹太人与Josephus及他的朋友躲到一个洞中 39个犹太人决定宁愿死也不要被敌人找到 于是决定了一个自杀方式 41个人排成一个圆圈 由第1个人开始报数 每报数到第3人该人就必须自杀 然后再由下一个重新报数 直到所有人都自杀身亡为止 然而Josephus 和他的朋友并不想遵从 Josephus要他的朋友先假装遵从 他将朋友与自己安排在第16个与第31个位置 于是逃过了这场死亡游戏 如何用循环链表来求解Josephu问题 参考文献 编辑 高一凡 数据结构 算法实现及解析 2004年10月第2版 西安 西安电子科技大学出版社 ISBN 9787560611761 中文 取自 https zh wikipedia org w index php title 循环链表 amp oldid 63799151, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。