数组有上界和下界,数组的元素在上下界内是连续的。
存储10,20,30,40,50的数组的示意图如下:

数组的特点是:数据是连续的;随机访问速度快。
数组中稍微复杂一点的是多维数组和动态数组。对于C语言而言,多维数组本质上也是通过一维数组实现的。至于动态数组,是指数组的容量能动态增长的数组;对于C语言而言,若要提供动态数组,需要手动实现;而对于C++而言,STL提供了Vector;对于Java而言,Collection集合中提供了ArrayList和Vector。
单向链表(单链表)是链表的一种,它由节点组成,每个节点都包含下一个节点的指针。
单链表的示意图如下:

表头为空,表头的后继节点是"节点10"(数据为10的节点),"节点10"的后继节点是"节点20"(数据为10的节点),...
单链表删除节点

删除"节点30"
删除之前:"节点20" 的后继节点为"节点30",而"节点30" 的后继节点为"节点40"。
删除之后:"节点20" 的后继节点为"节点40"。
单链表添加节点

在"节点10"与"节点20"之间添加"节点15"
添加之前:"节点10" 的后继节点为"节点20"。
添加之后:"节点10" 的后继节点为"节点15",而"节点15" 的后继节点为"节点20"。
单链表的特点是:节点的链接方向是单向的;相对于数组来说,单链表的的随机访问速度较慢,但是单链表删除/添加数据的效率很高。
双向链表(双链表)是链表的一种。和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
双链表的示意图如下:

表头为空,表头的后继节点为"节点10"(数据为10的节点);"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前继节点是"节点10";"节点20"的后继节点是"节点30","节点30"的前继节点是"节点20";...;末尾节点的后继节点是表头。
双链表删除节点

删除"节点30"
删除之前:"节点20"的后继节点为"节点30","节点30" 的前继节点为"节点20"。"节点30"的后继节点为"节点40","节点40" 的前继节点为"节点30"。
删除之后:"节点20"的后继节点为"节点40","节点40" 的前继节点为"节点20"。
双链表添加节点

在"节点10"与"节点20"之间添加"节点15"
添加之前:"节点10"的后继节点为"节点20","节点20" 的前继节点为"节点10"。
添加之后:"节点10"的后继节点为"节点15","节点15" 的前继节点为"节点10"。"节点15"的后继节点为"节点20","节点20" 的前继节点为"节点15"。
下面介绍双链表的实现,分别介绍C/C++/Java三种实现。
实现代码
- #include
- #include "double_link.h"
- void int_test()
- {
- int iarr[4] = {10, 20, 30, 40};
-
- printf("\n----%s----\n", __func__);
- create_dlink(); // 创建双向链表
-
- dlink_insert(0, &iarr[0]); // 向双向链表的表头插入数据
- dlink_insert(0, &iarr[1]); // 向双向链表的表头插入数据
- dlink_insert(0, &iarr[2]); // 向双向链表的表头插入数据
-
- printf("dlink_is_empty()=%d\n", dlink_is_empty()); // 双向链表是否为空
- printf("dlink_size()=%d\n", dlink_size()); // 双向链表的大小
-
- // 打印双向链表中的全部数据
- int i;
- int *p;
- int sz = dlink_size();
- for (i=0; i
- {
- p = (int *)dlink_get(i);
- printf("dlink_get(%d)=%d\n", i, *p);
- }
-
- destroy_dlink();
- }
-
- void string_test()
- {
- char* sarr[4] = {"ten", "twenty", "thirty", "forty"};
-
- printf("\n----%s----\n", __func__);
- create_dlink(); // 创建双向链表
-
- dlink_insert(0, sarr[0]); // 向双向链表的表头插入数据
- dlink_insert(0, sarr[1]); // 向双向链表的表头插入数据
- dlink_insert(0, sarr[2]); // 向双向链表的表头插入数据
-
- printf("dlink_is_empty()=%d\n", dlink_is_empty()); // 双向链表是否为空
- printf("dlink_size()=%d\n", dlink_size()); // 双向链表的大小
-
- // 打印双向链表中的全部数据
- int i;
- char *p;
- int sz = dlink_size();
- for (i=0; i
- {
- p = (char *)dlink_get(i);
- printf("dlink_get(%d)=%s\n", i, p);
- }
-
- destroy_dlink();
- }
-
- typedef struct tag_stu
- {
- int id;
- char name[20];
- }stu;
-
- static stu arr_stu[] =
- {
- {10, "sky"},
- {20, "jody"},
- {30, "vic"},
- {40, "dan"},
- };
- #define ARR_STU_SIZE ( (sizeof(arr_stu)) / (sizeof(arr_stu[0])) )
-
- void object_test()
- {
- printf("\n----%s----\n", __func__);
- create_dlink(); // 创建双向链表
-
- dlink_insert(0, &arr_stu[0]); // 向双向链表的表头插入数据
- dlink_insert(0, &arr_stu[1]); // 向双向链表的表头插入数据
- dlink_insert(0, &arr_stu[2]); // 向双向链表的表头插入数据
-
- printf("dlink_is_empty()=%d\n", dlink_is_empty()); // 双向链表是否为空
- printf("dlink_size()=%d\n", dlink_size()); // 双向链表的大小
-
- // 打印双向链表中的全部数据
- int i;
- int sz = dlink_size();
- stu *p;
- for (i=0; i
- {
- p = (stu *)dlink_get(i);
- printf("dlink_get(%d)=[%d, %s]\n", i, p->id, p->name);
- }
-
- destroy_dlink();
- }
-
- int main()
- {
- int_test(); // 演示向双向链表操作“int数据”。
- string_test(); // 演示向双向链表操作“字符串数据”。
- object_test(); // 演示向双向链表操作“对象”。
-
- return 0;
- }
2c++实现双链表
实现代码
- #ifndef DOUBLE_LINK_HXX
- #define DOUBLE_LINK_HXX
-
- #include
- using namespace std;
-
- template<class T>
- struct DNode
- {
- public:
- T value;
- DNode *prev;
- DNode *next;
- public:
- DNode() { }
- DNode(T t, DNode *prev, DNode *next) {
- this->value = t;
- this->prev = prev;
- this->next = next;
- }
- };
-
- template<class T>
- class DoubleLink
- {
- public:
- DoubleLink();
- ~DoubleLink();
-
- int size();
- int is_empty();
-
- T get(int index);
- T get_first();
- T get_last();
-
- int insert(int index, T t);
- int insert_first(T t);
- int append_last(T t);
-
- int del(int index);
- int delete_first();
- int delete_last();
-
- private:
- int count;
- DNode
*phead; - private:
- DNode
*get_node(int index) ; - };
-
- template<class T>
- DoubleLink
::DoubleLink() : count(0) - {
- // 创建“表头”。注意:表头没有存储数据!
- phead = new DNode
(); - phead->prev = phead->next = phead;
- // 设置链表计数为0
- //count = 0;
- }
-
- // 析构函数
- template<class T>
- DoubleLink
::~DoubleLink() - {
- // 删除所有的节点
- DNode
* ptmp; - DNode
* pnode = phead->next; - while (pnode != phead)
- {
- ptmp = pnode;
- pnode=pnode->next;
- delete ptmp;
- }
-
- // 删除"表头"
- delete phead;
- phead = NULL;
- }
-
- // 返回节点数目
- template<class T>
- int DoubleLink
::size() - {
- return count;
- }
-
- // 返回链表是否为空
- template<class T>
- int DoubleLink
::is_empty() - {
- return count==0;
- }
-
- // 获取第index位置的节点
- template<class T>
- DNode
* DoubleLink::get_node(int index) - {
- // 判断参数有效性
- if (index<0 || index>=count)
- {
- cout << "get node failed! the index in out of bound!" << endl;
- return NULL;
- }
-
- // 正向查找
- if (index <= count/2)
- {
- int i=0;
- DNode
* pindex = phead->next; - while (i++ < index) {
- pindex = pindex->next;
- }
-
- return pindex;
- }
-
- // 反向查找
- int j=0;
- int rindex = count - index -1;
- DNode
* prindex = phead->prev; - while (j++ < rindex) {
- prindex = prindex->prev;
- }
-
- return prindex;
- }
-
- // 获取第index位置的节点的值
- template<class T>
- T DoubleLink
::get(int index) - {
- return get_node(index)->value;
- }
-
- // 获取第1个节点的值
- template<class T>
- T DoubleLink
::get_first() - {
- return get_node(0)->value;
- }
-
- // 获取最后一个节点的值
- template<class T>
- T DoubleLink
::get_last() - {
- return get_node(count-1)->value;
- }
-
- // 将节点插入到第index位置之前
- template<class T>
- int DoubleLink
::insert(int index, T t) - {
- if (index == 0)
- return insert_first(t);
-
- DNode
* pindex = get_node(index); - DNode
* pnode = new DNode(t, pindex->prev, pindex); - pindex->prev->next = pnode;
- pindex->prev = pnode;
- count++;
-
- return 0;
- }
-
- // 将节点插入第一个节点处。
- template<class T>
- int DoubleLink
::insert_first(T t) - {
- DNode
* pnode = new DNode(t, phead, phead->next); - phead->next->prev = pnode;
- phead->next = pnode;
- count++;
-
- return 0;
- }
-
- // 将节点追加到链表的末尾
- template<class T>
- int DoubleLink
::append_last(T t) - {
- DNode
* pnode = new DNode(t, phead->prev, phead); - phead->prev->next = pnode;
- phead->prev = pnode;
- count++;
-
- return 0;
- }
-
- // 删除index位置的节点
- template<class T>
- int DoubleLink
::del(int index) - {
- DNode
* pindex = get_node(index); - pindex->next->prev = pindex->prev;
- pindex->prev->next = pindex->next;
- delete pindex;
- count--;
-
- return 0;
- }
-
- // 删除第一个节点
- template<class T>
- int DoubleLink
::delete_first() - {
- return del(0);
- }
-
- // 删除最后一个节点
- template<class T>
- int DoubleLink
::delete_last() - {
- return del(count-1);
- }
-
- #endif
-
相关阅读:
CCNA课程实验-14-Final_Lab
c++之旅第七弹——继承
初探PHP开源采集器----蓝天采集器
vue项目启动npm install和npm run serve时出现错误Failed to resolve loader:node-sass
linux安装zookeeper
【软件与系统安全笔记】六、恶意代码的机理及其防护
《荒野大镖客》游戏emp.dll丢失的修复方法,快速解决找不到emp.dll问题
Nautilus Chain全球行分享会,上海站圆满举办
导入现有项目maven到IDE的过程记录
flutter简单的本地草稿箱功能
-
原文地址:https://blog.csdn.net/SB202211/article/details/125865336