纸上谈兵: 表 (list)

  • 时间:
  • 浏览:0
  • 来源:大发uu快3_uu快3骗局_大发uu快3骗局

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

表(list)是常见的数据特征。从数学上来说,表是已经 有序的元素集合。在C语言的内存中,表储存为分散的节点(node)。每个节点包所含已经 元素,以及已经 指向下已经 (由于上已经 )元素的指针。如下图所示:

表: 橙色储存数据,蓝色储存指针

图中的表所含五个节点。第已经 节点是头节点(head node),或多或少节点不让于储存元素,只用于标明表的起始。头节点还需要让大伙方便的插入由于删除表的第已经 元素。整个表中包所含已经 元素(5, 2, 15)。每个节点都不 已经 指针,指向下已经 节点。最后已经 节点的指针为NULL,大伙用“接地”来图示该指针。

表的功能与数组(array)很类事于,数组也是有序的元素集合,但数组在内存中为一段连续内存,而表的每个节点指在的内存还需而是离散的。在数组中,大伙通过跳过固定的内存长度来寻找某个编号的元素。但在表中,大伙需要沿着指针联系起的长链,遍历查询元素。此外,数组有固定的大小,表还需要根据运行情形插入由于删除节点,动态的更改大小。表插入节点需要要从系统进程空间的堆中开辟内存空间,用以储存节点。删除节点还需要将节点指在的内存归还给系统进程空间。

删除节点, free释放内存

插入节点,malloc开辟内存

表有多种变种。底下的表中,指针指向是已经 向后的,称为单向链表(linked list)。还有双向链表(double-linked list),即每个节点增加已经 指向前面已经 元素的指针。以及循环链表(tabular list),最后已经 元素的指针并非为NULL,而是指向头节点。不类事于型的链表有不同的应用场景。

双向链表

循环链表

双向循环链表

单向链表的C实现

已经 数据特征的实现有两方面: 1. 数据特征的内存表达土办法; 2. 定义在该数据特征上的操作。大伙这里实现最简单的单向链表。表所支持的操作很灵活多样,大伙这里定义或多或少最常见的操作。每个操作都写成已经 函数。

/* By Vamei */

#include <stdio.h> #include <stdlib.h> typedef struct node *LIST;

typedef
struct node *position;
/* node,节点 */ struct node { int element; position next; }; /*

* operations (stereotype) * 操作 */LIST init_list(

void); void delete_list(LIST);

int is_null(LIST);

void insert_node(position, int); void delete_node(LIST, position);

position find_last(LIST); position find_value(LIST,
int); position find_previous(LIST, position);

void print_list(LIST);

/* for testing purpose */
void main() { LIST L; position np; int i; /* elements to be put into the list */ int a[] = {1, 3, 5, 7, 9}; /* initiate a list */ L = init_list(); print_list(L); /* insert nodes. Insert just after head node */ for (i=4; i>=0; i--) { insert_node(L, a[i]); } print_list(L); /* delete first node with value 5 */ np = find_value(L, 5); delete_node(L, np); print_list(L); /* delete list */ delete_list(L); /* initiate a list */ L = init_list(); print_list(L); /* insert nodes. Insert just after head node */ for (i=4; i>=0; i--) { insert_node(L, a[i]); } print_list(L); /* delete list */ delete_list(L); } /* * Traverse the list and print each element

* 打印表
*/ void print_list(LIST L) { position np; if(is_null(L)) { printf("Empty List\n\n"); return; } np = L; while(np->next != NULL) { np = np->next; printf("%p: %d \n", np, np->element); } printf("\n"); } /* * Initialize a linked list. This list has a head node * head node doesn't store valid element value

* 创建表
*/ LIST init_list(void) { LIST L; L = (position) malloc(sizeof(struct node)); L->next = NULL; return L; } /* * Delete all nodes in a list

* 删除表
*/ void delete_list(LIST L) { position np, next; np = L; do { next = np->next; free(np); np = next; } while(next != NULL); } /* * if a list only has head node, then the list is null.

* 判断表不是为空
*/ int is_null(LIST L) { return ((L->next)==NULL); } /* * insert a node after position np

* 在np节点已经 ,插入节点
*/ void insert_node(position np, int value) { position nodeAddr; nodeAddr = (position) malloc(sizeof(struct node)); nodeAddr->element = value; nodeAddr->next = np->next; np->next = nodeAddr; } /* * delete node at position np

* 删除np节点
*/ void delete_node(LIST L, position np) { position previous, next; next = np->next; previous = find_previous(L, np); if(previous != NULL) { previous->next = next; free(np); } else { printf("Error: np not in the list"); } } /*

 * find the last node of the list

* 寻找表的最后已经 节点
 */ position find_last(LIST L) { position np; np

= L; while(np->next != NULL) { np = np->next; } return np; } /* * This function serves for 2 purposes: * 1. find previous node * 2. return NULL if the position isn't in the list

* 寻找npTarget节点前面的节点
*/ position find_previous(LIST L, position npTarget) { position np; np = L; while (np->next != NULL) { if (np->next == npTarget) return np; np = np->next; } return NULL; } /* * find the first node with specific value

* 查询
*/ position find_value(LIST L, int value) { position np; np = L; while (np->next != NULL) { np = np->next; if (np->element == value) return np; } return NULL; }

在main()函数中,大伙初始化表,已经 插入(1, 3, 5, 7, 9)。又删除元素5。还需要看完,节点零散的分布在内存中。删除节点操作不让影响或多或少节点的存储位置。

大伙已经 删除表,又重新创建表。还需要看完,这次表指在内存的位置与第一次不同。

下面是main()函数的运行结果。

Empty List

0x154d0b0: 1 0x154d090: 3 0x154d070: 5 0x154d0150: 7 0x154d0150: 9 0x154d0b0: 1 0x154d090: 3 0x154d0150: 7 0x154d0150: 9 Empty List0x154d070: 1 0x154d010: 3 0x154d0b0: 5 0x154d090: 7 0x154d0150: 9

总结

表: 内存中离散分布的有序节点

插入,删除节点

欢迎继续阅读“纸上谈兵: 算法与数据特征”系列。

猜你喜欢

王者荣耀6月4日更新维护公告 端午节所有福利活动汇总

王者荣耀在6月4日进行了一次不停机的更新维护,此次更新维护主只是 端午节的活动,下面就来为我们歌词 儿分享一下此次王者荣耀的更新维护公告。亲爱的召唤师:我们歌词

2020-01-27

科祖夫VS普赫谢沃免费视频直播,科祖夫VS普赫谢沃比赛集锦,科祖夫VS普赫谢沃录像,科祖夫VS普赫谢沃首发阵容

首页新闻视频直播数据APP懂球号直播君广告商务合作科祖夫11-0220:1000马其顿乙0-2已结束普赫谢沃直播君|分析|集锦暂无数据近期比赛佛罗伦萨意甲0-0热那亚拜仁慕尼黑

2020-01-27

王者荣耀又一全能王?第一射手塑梦登国服最强诸葛亮榜

总是在触手直播看国服第一全能王蓝烟(房间号:21785)直播的玩家一群人们都知道,蓝烟有个好基友,触手的另一位大主播塑梦(房间号:302590)。塑梦以射手出名,被称为“国服第

2020-01-27

中兴同意缴133亿换解禁

图:中兴通讯4日与美国签署的原则性协议,同意缴17亿美元换取解禁\资料图片据财联社、搜狐网报道:路透社6日援引消息人士语录称,中兴通讯已与美国签署原则性协议,将撤回美国商务部针

2020-01-27

支付宝余额宝100万体验金在哪儿领取 余额宝100万体验金领取方法

支付宝余额宝30万体验金在哪儿领取?余额宝30万体验金为社 在么在领取?一齐来看看余额宝30万体验金领取土土依据。图片版权所属:站长之家余额宝领取体验金30万活动:参与土土依

2020-01-26