• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入解析C++的循环链表与双向链表设计的API实现

深入解析C++的循环链表与双向链表设计的API实现

作者:YoferZhang 字体:[增加 减小] 来源:互联网 时间:2017-05-28

YoferZhang 通过本文主要向大家介绍了c++双向链表,c++单链表,c++单链表的建立,c++单链表的实现,c++循环链表等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

循环链表设计与API实现
基本概念
循环链表的定义:将单链表中最后一个数据元素的next指针指向第一个元素

2016314164208430.jpg (661×134)

循环链表拥有单链表的所有操作

  • 创建链表
  • 销毁链表
  • 获取链表长度
  • 清空链表
  • 获取第pos个元素操作
  • 插入元素到位置pos
  • 删除位置pos处的元素

新增功能:游标的定义

在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。

2016314164239106.jpg (668×198)

循环链表新操作
将游标重置指向链表中的第一个数据元素

CircleListNode* CircleList_Reset(CircleList* list);
</div>

获取当前游标指向的数据元素

CircleListNode* CircleList_Current(CircleList* list);
</div>

将游标移动指向到链表中的下一个数据元素

CircleListNode* CircleList_Next(CircleList* list);
</div>

直接指定删除链表中的某个数据元素

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node); 
// 根据元素的值 删除 元素 pk根据元素的位置 删除 元素
</div>

最后加了一个循环链表的应用:求解约瑟夫问题
约瑟夫问题-循环链表典型应用
n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。

2016314164321374.jpg (707×365)

代码:

// circlelist.h 
// 循环链表API声明 
 
#ifndef _CIRCLELIST_H_ 
#define _CIRCLELIST_H_ 
 
typedef void CircleList; 
 
typedef struct _tag_CircleListNode 
{ 
  struct _tag_CircleListNode *next; 
}CircleListNode; 
 
// 创建链表 
CircleList* CircleList_Create(); 
 
// 销毁链表 
void CircleList_Destroy(CircleList* list); 
 
// 清空链表 
void CircleList_Clear(CircleList* list); 
 
// 获取链表的长度 
int CircleList_Length(CircleList* list); 
 
// 在pos位置插入结点node 
int CircleList_Insert(CircleList* list,CircleListNode* node, int pos); 
 
// 获取pos位置的结点 
CircleListNode* CircleList_Get(CircleList* list, int pos); 
 
// 删除pos位置的结点 
CircleListNode* CircleList_Delete(CircleList* list, int pos); 
 
// 根据结点的值进行数据删除 
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node); 
 
// 重置游标 
CircleListNode* CircleList_Reset(CircleList* list); 
 
// 获取当前游标所指结点 
CircleListNode* CircleList_Current(CircleList* list); 
 
// 将原始游标所指结点返回给上层,然后让游标移到下一个结点 
CircleListNode* CircleList_Next(CircleList* list); 
 
#endif 

</div>
// circlelist.cpp 
// 循环链表API实现 
 
#include <iostream> 
#include <cstdio> 
#include "circlelist.h" 
 
typedef struct _tag_CircleList 
{ 
  CircleListNode header; 
  CircleListNode *silder; 
  int length; 
}TCircleList; 
 
// 创建链表 
CircleList* CircleList_Create() 
{ 
  TCircleList *ret = (TCircleList *)malloc(sizeof(TCircleList)); 
  if (ret == NULL) { 
    return NULL; 
  } 
 
  // 初始化 
  ret->header.next = NULL; 
  ret->silder = NULL; 
  ret->length = 0; 
 
  return ret; 
} 
 
// 销毁链表 
void CircleList_Destroy(CircleList* list) 
{ 
  if (list == NULL) { 
    return; 
  } 
  free(list); 
  return; 
} 
 
// 清空链表 
void CircleList_Clear(CircleList* list) 
{ 
  if (list == NULL) { 
    return; 
  } 
  TCircleList *tList = (TCircleList *)list; 
  tList->header.next = NULL; 
  tList->silder = NULL; 
  tList->length = 0; 
 
  return; 
} 
 
// 获取链表的长度 
int CircleList_Length(CircleList* list) 
{ 
  if (list == NULL) { 
    return -1; 
  } 
  TCircleList *tList = (TCircleList *)list; 
  return tList->length; 
} 
 
// 在pos位置插入结点node 
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) 
{ 
  if (list == NULL || node == NULL || pos < 0) { 
    return -1; 
  } 
 
  TCircleList *tList = (TCircleList *)list; 
 
  CircleListNode *cur = (CircleListNode *)tList; 
 
  for (int i = 0; i < pos; ++i) { 
    cur = cur->next; 
  } 
 
  node->next = cur->next; 
  cur->next = node; 
 
  // 如果是第一次插入 
  if (tList->length == 0) { 
    tList->silder = node; 
  } 
 
  ++tList->length; // 记得长度加1 
 
  // 如果是头插法 
  if (cur == (CircleListNode *)tList) { 
    // 获取最后一个元素 
    CircleListNode *last = CircleList_Get(tList, tList->length - 1); 
    last->next = cur->next; 
  } 
 
  return 0; 
} 
 
// 获取pos位置的结点 
CircleListNode* CircleList_Get(CircleList* list, int pos) 
{ 
  // 因为是循环链表,所以这里不需要排除pos>length的情况 
  if (list == NULL || pos < 0) { 
    return NULL; 
  } 
 
  TCircleList *tList = (TCircleList *)list; 
  CircleListNode *cur = (CircleListNode *)tList; 
 
  for (int i = 0; i < pos; ++i) { 
    cur = cur->next; 
  } 
 
  return cur->next; 
} 
 
// 删除pos位置的结点 
CircleListNode* CircleList_Delete(CircleList* list, int pos) 
{ 
  TCircleList *tList = (TCircleList *)list; 
  CircleListNode *ret = NULL; 
 
  if (tList != NULL && pos >= 0 && tList->length > 0) { 
    CircleListNode *cur = (CircleListNode *)tList; 
    for (int i = 0; i < pos; ++i) { 
      cur = cur->next; 
    } 
 
    // 若删除头结点,需要求出尾结点 
    CircleListNode *last = NULL; 
    if (cur == (CircleListNode *)tList) { 
      last = CircleList_Get(tList, tList->length - 1); 
    } 
 
    ret = cur->next; 
    cur->next = ret->next; 
 
    --tList->length; 
 
    // 若删除头结点 
    if (last != NULL) { 
      tList->header.next = ret->next; 
      last->next = ret->next; 
    } 
 
    // 若删除的元素为游标所指的元素 
    if (tList->silder == ret) { 
      tList->silder = ret->next; 
    } 
 
    // 若删除元素后链表长度为0 
    if (tList->length == 0) { 
      tList->header.next = NULL; 
      tList->silder = NULL; 
    } 
  } 
 
  return ret; 
} 
 
// 根据结点的值进行数据删除 
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node) 
{ 
  TCircleList *tList = (TCircleList *)list; 
  CircleListNode *ret = NULL; 
 
  if (list != NULL && node != NULL) { 
    CircleListNode *cur = (CircleListNode *)tList; 
    int i = 0; 
    for (i = 0; i < tList->length; ++i) { 
      if (cur->next == node) { 
        ret = cur->next; 
        break; 
      } 
 
      cur = cur->next; 
    } 
 
    // 如果找到 
    if (ret != NULL) { 
      CircleList_Delete(tList, i); 
    } 
  } 
 
  return ret; 
} 
 
// 重置游标 
CircleListNode* CircleList_Reset(CircleList* list) 
{ 
  TCircleList *tList = (TCircleList *)list; 
  CircleListNode* ret = NULL; 
 
  if (list != NULL) { 
    tList->silder = tList->header.next; 
    ret = tList->silder; 
  } 
 
  return NULL; 
} 
 
// 获取当前游标所指结点 
CircleListNode* CircleList_Current(CircleList* list) 
{ 
  TCircleList *tList = (TCircleList *)list; 
  CircleListNode* ret = NULL; 
  if (list != NULL) { 
    ret = tList->silder; 
  } 
 
  return ret; 
} 
 
// 将原始游标所指结点返回给上层,然后让游标移到下一个结点 
CircleListNode* CircleList_Next(Circle



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++ 数据结构链表的实现代码
  • 关于双向链表的增删改查和排序的C++实现
  • 深入解析C++的循环链表与双向链表设计的API实现
  • c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)
  • C++ 模版双向链表的实现详解
  • 如何用C++实现双向循环链表
  • C++ 构造双向链表的实现代码

相关文章

  • 2017-05-28CStdioFile的用法详细解析
  • 2017-05-28解析sizeof, strlen, 指针以及数组作为函数参数的应用
  • 2017-05-28浅析C#与C++相关概念的比较
  • 2017-05-28C++实现将数组中的值反转
  • 2017-05-28C 创建链表并将信息存储在二进制文件中读取的实例代码
  • 2017-05-28基于C语言实现的迷宫游戏代码
  • 2017-05-28C++德州扑克的核心规则算法
  • 2017-12-31数据结构 多关键字排序
  • 2017-05-28解析c中stdout与stderr容易忽视的一些细节
  • 2017-05-28在vs2010中,输出当前文件路径与源文件当前行号的解决方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++基础学生管理系统
    • C++编程中队内联函数的理解和使用
    • visual studio 2013中配置opencv图文教程 Opencv2.4.9安装配置教程
    • c语言B树深入理解
    • 如何在程序中判断VS的版本(实现方法详解)
    • 在Linux下编译C或C++程序的教程
    • C语言完美实现动态数组代码分享
    • c语言文件读写示例(c语言文件操作)
    • 如何用C++实现双向循环链表
    • C++中strtok()函数的用法介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有