算法实例_链表结构 By:比方

前一章,我们说到了顺序表结构,而顺序表也存在一些的缺点。

在插入或者删除节点的时候,需要移动的数据比较大,如果顺序表结构比较大,有时候比较难以分配足够的连续存储空间,可能会导致内存分配失败,而导致无法存储。

而今天我们讲解的链表结构则可以很好的解决这个问题,链表的结构是一种动态存储分配的结构形式,可以根据需要动态申请所需的内存单元。

一.什么是链表结构?

a)         我们用head来表示头节点。

b)         数据部分保存的是存储的数据,地址地方指向下一个数据的起始部分,依次向下类推,一环套用一环,所以称之为链表。

c)         如果想查找值得的节点,则必须从链表头开始找起,这也算链表的不足之处吧。

d)         链表有多种结构,一种是单链表,而另外一种则是双链表,单链表如下图所示

e)         单链表只指向下一个节点,而双链表则拥有两个指针,一个分别指向他的下一个数据地址,另一个指向他的上一个数据节点。

首先是数据的准备,然后是定义一个节点结构和链表的结构,

其次是追加节点,插入节点,删除节点,计算链表的长度等

 1 // Listed.cpp : Defines the entry point for the console application.
 2 //
 3
 4 #include "stdafx.h"
 5 #include <stdlib.h>
 6 #include <string.h>
 7
 8
 9 typedef struct   //定义数据
10 {
11     char Key[12];
12     char Name[20];
13     int  Age;
14 }Data;
15
16 typedef struct  Node//定义链表的结构
17 {
18     Data NodeData;   //数据链表
19     struct Node *NextNode;
20
21 }LType;

添加一个新的数据到链表中//尾部插入数据

 1 LType *ListAddEnd(LType *Head,Data NodeData)
 2 {
 3     LType *Node,*htemp;
 4     if (!(Node = (LType*)malloc(sizeof(LType))))//申请需要的内存空间
 5     {
 6         printf("申请内存失败\r\n");
 7         return NULL;
 8     }
 9     else
10     {
11         Node->NodeData = NodeData;                 //保存数据
12         Node->NextNode = NULL;                     //设置为节点表尾为空
13         if (Head == NULL)      //判断链表是不是空链表,头指针
14         {
15             Head = Node;
16             return Head;
17         }
18         htemp = Head;
19         while (htemp->NextNode != NULL)           //查找链表的最后一个
20         {
21             htemp = htemp->NextNode;
22         }
23         htemp->NextNode = Node;
24         return Head;
25     }
26
27 }

添加一个新的数据到链表中//头部插入数据

 1 LType *ListAddFrist(LType *Head,Data NodeData)
 2 {
 3     LType *Node;
 4     if (!(Node = (LType*)malloc(sizeof(LType))))//申请需要的内存空间
 5     {
 6         printf("申请内存失败\r\n");
 7         return NULL;
 8     }
 9     else
10     {
11         Node->NodeData = NodeData;   //保存数据
12         Node->NextNode = Head;       //指向头结点所指节点
13         Head = Node;                 //头指针指向新增节点
14
15         return Head;
16     }
17 }

//查找节点,比较关键字,从头指针开始查找

 1 LType *ListFindNode(LType *Head,char *Key)   //查找节点
 2 {
 3     LType *htemp;
 4     htemp = Head;                                  //保存链表的头指针
 5     while(htemp)                                   //继续向下寻找
 6     {
 7         if (strcmp(htemp->NodeData.Key,Key) == 0)  // 比较节点关键字是否相同
 8         {
 9             return htemp;                          // 返回该节点指针
10         }
11         htemp = htemp->NextNode;                   //返回下一个节点
12     }
13     return NULL;                                   //返回一个空的指针
14 }

//在指定的节点那里插入新的节点,让原先的下一个节点指向新的节点头部,让新节点的下一个地址指向原先的下一个节点的头部

 1 LType *ListInstNode(LType *Head,char *FindKey,Data NodeData)
 2 {
 3     LType *Node,*Nodetemp;
 4     if (!(Node = (LType*)malloc(sizeof(LType))))//申请需要的内存空间
 5     {
 6         printf("申请内存失败\r\n");
 7         return NULL;
 8     }
 9
10     Node->NodeData = NodeData;                  //保存节点的数据
11     Nodetemp = ListFindNode(Head,FindKey);      //如果找到了我们需要的数据,就在这里开始插入我们的新数据
12     if (Nodetemp)
13     {
14         Node->NextNode = Nodetemp->NextNode;    //新插入的节点指关键节点的下一个节点。
15         Nodetemp->NextNode = Node;              //设置关键节点指向新插入的节点。
16     }
17     else
18     {
19         printf("未找到插入的位置\r\n");
20         free(Node);
21     }
22     return Head;
23 }

//删除一个节点

 1 int ListDelect(LType *Head,char *Key)
 2 {
 3     LType *Node,*hTemp;
 4     hTemp = Head;  //当前头指针赋值给零时变量
 5     Node = Head;
 6     while(hTemp)
 7     {
 8         if (strcmp(hTemp->NodeData.Key,Key) == 0)         //找到关键词
 9         {
10             Node->NextNode = hTemp->NextNode;              //前一个节点指向当前节点的下一个节点上去。
11             free(hTemp);                                  //把找到的这个节点释放掉
12             return 1;
13         }
14         else
15         {
16             Node = hTemp;                                 //指向当前节点
17             hTemp = hTemp->NextNode;                      //指向下一个节点
18         }
19     }
20     return 0; //未能删除掉节点
21
22 }

//计算链表的长度

 1 int ListGetLength(LType *Head)
 2 {
 3     LType *hTemp;
 4     int Len = 0;
 5     hTemp = Head;
 6     while(hTemp)                   //遍历整个链表
 7
 8     {
 9         Len++;
10         hTemp = hTemp->NextNode;
11     }
12     return Len;                     //返回节点的数量
13
14 }
 1 void ListAllNode(LType *Head)  //遍历所有的链表
 2 {
 3     LType *hTemp;
 4     Data NodeData;
 5     hTemp = Head;
 6     printf("当前链表共有%d个节点,链表所有数据如下:\r\n",ListGetLength(Head));
 7     while(hTemp)
 8     {
 9         NodeData = hTemp->NodeData;
10         printf("关键词 : %s 名称 : %s 年龄 : %d\r\n",NodeData.Key,NodeData.Name,NodeData.Age);   //打印链表里面内容信息
11         hTemp = hTemp->NextNode;
12
13     }
14 }

主函数测试代码

 1 int main(int argc, char* argv[])
 2 {
 3     LType *Node,*Head = NULL;
 4     Data NodeData;
 5     char Key[10],FindKey[10];
 6
 7     printf("链表测试案例 插入新的节点,输入(标识,名字,年龄)\r\n");
 8     do
 9     {
10         fflush(stdin);
11         scanf("%s ",NodeData.Key);
12         if (strcmp(NodeData.Key,"0") == 0)
13         {
14             break;
15         }
16         else{
17             scanf("%s %d",NodeData.Name,&NodeData.Age);
18             Head = ListAddEnd(Head,NodeData);
19
20         }
21     } while (1);
22
23     ListAllNode(Head);  //显示所有节点
24
25
26
27     printf("插入节点(关键字 标识 姓名 年龄)用空格分开\r\n");
28     scanf("%s %s %s %d",&FindKey,NodeData.Key,NodeData.Name,NodeData.Age);
29     ListAllNode(Head);  //显示所有节点
30
31
32     system("pause");
33     return 0;
34 }

附件地址:http://pan.baidu.com/s/1mgmguRA

算法实例_链表结构 By:比方

时间: 2024-10-01 23:53:59

算法实例_链表结构 By:比方的相关文章

算法实例_线性表 By:比方

算法实例_线性表 By:比方 什么是线性表? 从线性表的功能逻辑上来看,线性表就是由n(n>=0)个数据元素的排序组合,数据由x1,x2,x3,...,xn结构有序的顺序排列. 线性表的结构和特点 1.              仅有一个开始节点x1,没有直接前趋节点,有妾只有一个直接后续节点x2: 2.              仅有一个终结节点xn,仅有一个前趋节点xn-1; 3.              对于同一个线性表,其中没一个数据的元素,都必须具备相同的数据结构类型, 且没一个元素

java数据结构和算法------线性表(链表结构)

1 package iYou.neugle.list; 2 3 public class MyChainList<T> { 4 // 向链表尾部添加元素 5 public Node<T> AddEnd(Node<T> head, T data) { 6 Node<T> node = new Node<T>(); 7 node.data = data; 8 if (head == null) { 9 head = node; 10 return h

Linear regression with multiple variables(多特征的线型回归)算法实例_梯度下降解法(Gradient DesentMulti)以及正规方程解法(Normal Equation)

%第一列为 size of House(feet^2),第二列为 number of bedroom,第三列为 price of House 1 2104,3,399900 2 1600,3,329900 3 2400,3,369000 4 1416,2,232000 5 3000,4,539900 6 1985,4,299900 7 1534,3,314900 8 1427,3,198999 9 1380,3,212000 10 1494,3,242500 11 1940,4,239999 1

javascript常用经典算法实例详解

javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与使用技巧,需要的朋友可以参考下 本文实例讲述了javascript常用算法.分享给大家供大家参考,具体如下: 入门级算法-线性查找-时间复杂度O(n)--相当于算法界中的HelloWorld ? 1 2 3 4 5 6 7 8 9 10 //线性搜索(入门HelloWorld) //A为数组,x为要

java数据结构与算法之双链表设计与实现

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/53047590 出自[zejian的博客] 关联文章: 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) ??上一篇文章分析顺序表和单链表,本篇就接着上篇继续聊链表,在单链表

数据结构与算法JavaScript (三) 链表

数据结构与算法JavaScript (三) 链表 我们可以看到在javascript概念中的队列与栈都是一种特殊的线性表的结构,也是一种比较简单的基于数组的顺序存储结构.由于 javascript的解释器针对数组都做了直接的优化,不会存在在很多编程语言中数组固定长度的问题(当数组填满后再添加就比较困难了,包括添加删除, 都是需要把数组中所有的元素全部都变换位置的,javascript的的数组确实直接给优化好了,如 push,pop,shift,unshift,split方法等等…) 线性表的顺序

[大话数据结构]线性表之单链表结构和顺序存储结构

线性表定义: 零个或者多个数据元素的有限序列.元素之间是有顺序的,如果元素存在多个,则第一个元素无前驱,最后一个元素无后继.其他每个元素都有且只有一个前驱和后继.并且数据元素的类型要相同. 线性表的抽象数据类型: ADT 线性表(List) Data 线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType. 其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素. 数据元素之间的关系是一对一的关系.

一步一步写算法(之图结构)

原文:一步一步写算法(之图结构) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 图是数据结构里面的重要一章.通过图,我们可以判断两个点之间是不是具有连通性:通过图,我们还可以计算两个点之间的最小距离是多少:通过图,我们还可以根据不同的要求,寻找不同的合适路径.当然,有的时候为了计算的需要,我们还需要从图中抽象出最小生成树,这样在遍历计算的时候就不需要持续判断是不是遇到了循环节点.当然,这所有的一切都是从图的表示开始的. 1)矩阵表示 矩

调试器开发实例_调试器框架设计

作为一个安全开发人员离不开调试器,它可以动态显示程序的执行过程,对于解决程序问题有极大的帮助,这些文章记录了我开发一个调试器雏形的过程,希望对你有帮助.或许我写的代码很拙劣,还请大家多多见谅! 我们使用  Microsoft Visual Studio 6.0 VC编译器来作为我们的开发工具想对一个程序进行调试,首先要做的当然是启动这个程序,这要使用CreateProcess这个Windows API来完成.例如: 1 // LilisiDebug.cpp : Defines the entry