收藏 分享(赏)

C++链表.doc

上传人:gnk289057 文档编号:9468641 上传时间:2019-08-09 格式:DOC 页数:19 大小:66.50KB
下载 相关 举报
C++链表.doc_第1页
第1页 / 共19页
C++链表.doc_第2页
第2页 / 共19页
C++链表.doc_第3页
第3页 / 共19页
C++链表.doc_第4页
第4页 / 共19页
C++链表.doc_第5页
第5页 / 共19页
点击查看更多>>
资源描述

1、C+链表【双向链表】.建立一个双向链表?1 typedef struct DbNode2 3 int data; /节点数据4 DbNode *left; /前驱节点指针5 DbNode *right; /后继节点指针6 DbNode;(1)建立双向链表:为方便,这里定义了三个函数:q CreateNode()根据数据来创建一个节点,返回新创建的节点。q CreateList()函数根据一个节点数据创建链表的表头,返回表头节点。q AppendNode ()函数总在表尾插入新节点(其内部调用CreateNode()生成节点) ,返回表头节点。1 /根据数据创建创建节点2 DbNode *Cre

2、ateNode(int data)3 4 DbNode *pnode = (DbNode *)malloc(sizeof(DbNode);5 pnode-data = data;6 pnode-left = pnode-right = pnode; /创建新节点时7 /让其前驱和后继指针都指向自身8 return pnode;910 11 /创建链表12 DbNode *CreateList(int head) /参数给出表头节点数据13 /表头节点不作为存放有意义数据的节点14 DbNode *pnode = (DbNode *)malloc(sizeof(DbNode);15 pnode-

3、data = head;16 pnode-left = pnode-right = pnode;1718 return pnode;19 20 21 /插入新节点,总是在表尾插入; 返回表头节点22 DbNode *AppendNode(DbNode *head, int data) /参数 1是链表的表头节点,23 /参数 2是要插入的节点,其数据为 data24 DbNode *node = CreateNode(data); /创建数据为 data的新节点25 DbNode *p = head, *q;26 27 while(p != NULL)28 29 q = p;30 p = p-

4、right;31 32 q-right = node;33 node-left = q;3435 return head;36 我们可以使用其中的 CreateList()和 AppendNode()来生成一个链表,下面是一个数据生成从 0到 9含有 10个节点的循环链表。1 DbNode *head = CreateList(0); /生成表头,表头数据为 023 for (int i = 1; i right;12 while (pnode != NULL)13 14 pnode = pnode-right; /使用 right指针遍历15 count+; / 也可以打印16 17 18

5、return count;19 .查找双向链表节点?使用 right指针遍历,直至找到数据为 data的节点,如果找到节点,返回节点,否则返回 NULL。1 /查找节点,成功则返回满足条件的节点指针,否则返回NULL2 DbNode *FindNode(DbNode *head, int data) /参数 1是链表的表头节点3 /参数2是要查找的节点,其数据为 data4 DbNode *pnode = head;5 6 if (head = NULL) /链表为空时返回 NULL7 8 return NULL;9 10 11 /*找到数据或者到达链表末尾退出 while循环*/12 whi

6、le (pnode-right != NULL /使用 right指针遍历15 16 17 /没有找到数据为 data的节点,返回 NULL18 if (pnode-right = NULL)19 20 return NULL;21 2223 return pnode;24 +【单向链表】.如何创建一个单链表?链表节点的定义:typedef struct nodeint data; /节点内容node *next; /下一个节点node;单链表的创建:1 /创建单链表2 node *create()3 4 int i = 0; /链表中数据的个数5 node *head, *p, *q;6 i

7、nt x = 0;7 head = (node *)malloc(sizeof(node); /创建头节点89 while(1)10 11 printf(“Please input the data: “);12 scanf(“%d“, 13 if (x = 0) /data为 0时创建结束14 break;15 p = (node *)malloc(sizeof(node);16 p-data = x;17 if (+i = 1)18 /链表只有一个元素19 head-next = p; /连接到 head的后面20 21 else22 23 q-next = p; /连接到链表尾端24 2

8、5 q = p; /q指向末节点26 27 q-next = NULL; /链表的最后一个指针为 NULL28 return head;29 上面的代码中,使用 while循环每次从终端读入一个整型数据,并调用 malloc动态分配链表节点内存存储这个整型数据,然后再插入到单链表的末尾。最后当数据为 0时表示插入数据结束,此时把末尾节点的 next指针置为 NULL。.查找单链表中间元素?解析:这里使用一个只用一遍扫描的方法。描述如下:假设 mid指向当前已经扫描的子链表的中间元素,cur 指向当前以扫描链表的尾节点,那么继续扫描即移动 cur到 cur-next,这时只需判断一下应不应移动

9、mid到 mid-next就行了。所以一遍扫描就能找到中间位置。代码如下:1 node *search(node *head)2 3 int i = 0;4 int j = 0;5 node *current = NULL;6 node *middle = NULL;7 8 current = middle = head-next;9 while(current != NULL)10 11 if( i / 2 j)12 13 j+;14 middle = middle-next;15 16 i+;17 current = current-next;18 19 20 return middle;

10、21 .打印单向链表?解析:单链表的打印:1 /打印单链表2 void print(node *head)3 4 node *p;5 int index = 0;6 if (head-next = NULL) /链表为空7 8 printf(“Link is empty!n“);9 return;10 11 p = head-next;12 while(p != NULL) /遍历链表13 14 printf(“The %dth node is: %dn“, +index, p-data); /打印元素 - 也可计算单链表长度 count+;15 p = p-next;16 17 单链表的打印

11、与单链表的测长方法类似,使用 while循环进行遍历链表所有节点并打印各个节点内容,当遇到 NULL时结束循环。.查找单链表节点?单链表的查找节点:1 /查找单链表 pos位置的节点,返回节点指针2 /pos从 0开始,0 返回 head节点3 node *search_node(node *head, int pos)4 5 node *p = head-next;6 if (pos next) = NULL)24 /超出链表返回25 printf(“incorrect position to search node!n“);26 break;27 28 29 return p;30 .单链

12、表插入节点?解析:向单链表中某个位置(第 pos个节点)之后插入节点,这里分为插入到链表首部、插入到链表中间,以及链表尾端三种情况:1 /在单链表 pos位置处插入节点,返回链表头指针2 /pos从 0开始计算,0 表示插入到 head节点后面3 node *insert_node(node *head, int pos, int data)4 5 node *item = NULL;6 node *p;7 8 item = (node *)malloc(sizeof(node);9 item-data = data;10 if (pos = 0) /插入链表头后面11 12 head-nex

13、t = item; /head后面是 item13 return head;14 15 p = search_node(head, pos); /获得位置pos的节点指针16 if (p != NULL)17 18 item-next = p-next; /item指向原 pos节点的后一个节点19 p-next = item; /把item插入到 pos的后面20 21 return head;22 .单向链表删除节点?解析:单链表删除节点:1 /删除单链表的 pos位置的节点,返回链表头指针2 /pos从 1开始计算,1 表示删除 head后的第一个节点3 node *delete_nod

14、e(node *head, int pos)4 5 node *item = NULL;6 node *p = head-next;7 if (p = NULL) /链表为空8 9 printf(“link is empty!n“);10 return NULL;11 12 p = search_node(head, pos-1); /获得位置 pos的节点指针13 if (p != NULL 16 p-next = item-next;17 delete item; 18 19 return head;20 .单向链表的逆序?解析:这是一个经常被问到的面试题,也是一个非常基础的问题。比如一个

15、链表是这样的: 1-2-3-4-5 通过逆置后成为 5-4-3-2-1。最容易想到的方法是遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。1 node *reverse(node *head)2 3 node *p, *q, *r; 4 5 if (head-next = NULL) /链表为空6 7 return head;8 910 p = head-next;11 q = p-next; /保存原第二个节点12 p-next = NULL; /原第一个节点为末节点13 14 while(q != N

16、ULL) /遍历,各个节点的 next指针反转15 16 r = q-next;17 q-next = p;18 p = q;19 q = r;20 21 head-next = p; /新的第一个节点为原末节点22 return head;23 .单链表的正向排序?解析:下面试结构体定义和代码如下:1 typedef struct node2 3 int data;4 node *next;5 node;67 node* InsertSort(void)8 9 int data = 0;10 struct node *head=NULL,*New,*Cur,*Pre;11 while(1)1

17、2 13 printf(“please input the datan“); 14 scanf(“%d“, 15 if (data = 0) /输入 0结束16 17 break;18 19 New=(struct node*)malloc(sizeof(struct node);20 New-data = data; /新分配一个 node节点21 New-next = NULL;22 if(head = NULL)23 /第一次循环时对头节点赋值24 head=New;25 continue;26 27 if(New-data data)28 /head之前插入节点29 New-next

18、= head;30 head = New;31 continue;32 33 Cur = head;34 while(New-data Cur-data 38 Cur = Cur-next;39 40 if(Cur-data = New-data) /位置在中间41 /把 new节点插入到 Pre和 cur之间42 Pre-next = New;43 New-next = Cur;44 45 else /位置在末尾46 Cur-next = New; /把 new节点插入到 cur之后47 48 return head;49 .有序单链表的合并?已知两个链表 head1 和 head2 各自有

19、序,请把它们合并成一个链表依然有序。使用非递归方法以及递归方法。解析:首先介绍非递归方法。因为两个链表 head1 和 head2都是有序的,所以我们只需要找把较短链表的各个元素有序的插入到较长的链表之中就可以了。源代码如下:1 node* insert_node(node *head, node *item) /head != NULL2 3 node *p = head;4 node *q = NULL; /始终指向 p之前的节点5 6 while(p-data data 9 p = p-next;10 11 if (p = head) /插入到原头节点之前12 13 item-next

20、= p;14 return item;15 16 /插入到 q与 p之间之间17 q-next = item;18 item-next = p;19 return head;20 21 22 /* 两个有序链表进行合并 */23 node* merge(node* head1, node* head2)24 25 node* head; /合并后的头指针26 node *p; 27 node *nextP; /指向 p之后28 29 if ( head1 = NULL ) /有一个链表为空的情况,直接返回另一个链表30 31 return head2;32 33 else if ( head2

21、 = NULL )34 35 return head1;36 37 38 / 两个链表都不为空39 if(length(head1) = length(head2) /选取较短的链表40 /这样进行的插入次数要少些41 head = head1;42 p = head2;43 44 else45 46 head = head2;47 p = head1;48 49 50 while(p != NULL)51 52 nextP = p-next; /保存 p的下一个节点53 head = insert_node(head, p); /把 p插入到目标链表中54 p = nextP; /指向将要插

22、入的下一个节点55 56 57 return head;58 这里 insert_node()函数是有序的插入节点,注意与前面例题中的函数有区别,这里它传入的参数是 node*类型。然后在 merge()函数中(代码 5255行)循环把短链表中的所有节点插入到长链表中。接下来介绍非递归方法。比如有下面两个链表:链表 1:1-3-5链表 2:2-4-6递归方法的步骤如下:(1)比较链表 1和链表 2的第一个节点数据,由于 15)和链表 2再调用本过程,比较得到结果链表的第二个节点,即 2与 3比较得到 2。此时合并后的链表节点为 1-2。接下来的过程类似(2) ,如此递归知道两个链表的节点都被加

23、到结果链表中。1 node * MergeRecursive(node *head1, node *head2)2 3 node *head = NULL;4 5 if (head1 = NULL)6 7 return head2;8 9 if (head2 = NUL)10 11 return head1;12 13 14 if ( head1-data data )15 16 head = head1 ;17 head-next = MergeRecursive(head1-next,head2);18 19 else20 21 head = head2 ;22 head-next = MergeRecursive(head1,head2-next);23 24 25 return head ;26 下面是测试程序:1 int main()2 3 node *head1 = create(); /创建单链表 14 node *head2 = create(); /创建单链表 25 /node *head = merge(head1, head2);6 node *head = MergeRecursive(head1, head2);7 print(head);89 return 0;10 这里使用 merge()函数和 MergeRecursive()函数测试,结果一致。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报