c/c++常用算法(2) -- 数据结构(线性表的链式存储)
来源:互联网 发布:华东师范大学网络研修 编辑:程序博客网 时间:2024/05/16 07:07
一、线性表的链式存储结构
链式存储:用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性表简称线性链表。
存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。
链表中结点的逻辑顺序和物理顺序不一定相同。为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址(或位置),称为指针(pointer)或链(link),这两部分组成了链表中的结点结构,如图2-2所示。
data :数据域,存放结点的值
next:指针域,存放结点的直接后继的地址
表是通过每个结点的指针域将线性表的n个结点按其逻辑次序链接在一起的。
每一个结只包含一个指针域的链表,称为单链表。
为操作方便,总是在链表的第一个结点之前附设一个头结点(头指针)head指向第一个结点。头结点的数据域可以不存储任何信息(或链表长度等信息)。
二、结点描述与实现
1 .描述
C语言中用带指针的结构体类型来描述
typedef struct Lnode{ ElemType data; /*数据域,保存结点的值 */ struct Lnode *next; /*指针域*/}LNode; /*结点的类型 */
2.实现
结点是通过动态分配和释放来的实现,即需要时分配,不需要时释放。实现时是分别使用C语言提供的标准函数:malloc(),realloc(),sizeof(),free() 。
动态分配 p=(LNode*)malloc(sizeof(LNode));
函数malloc分配了一个类型为LNode的结点变量的空间,并将其首地址放入指针变量p中。
动态释放 free(p);
系统回收由指针变量p所指向的内存区。P必须是最近一次调用malloc函数时的返回值。
3.代码:
List.h
#ifndef __CHelloWorld__List__#define __CHelloWorld__List__#include <iostream>using namespace std;typedef struct{ char key[10]; //结点的关键字 char name[20]; int age;}Data; //结点类型typedef struct Node //定义链表结构{ Data nodeData; struct Node *nextNode;}CLType;class List{public: CLType *CLAddEnd(CLType* head,Data nodeData); //追加结点(链表尾增加结点) CLType *CLAddFirst(CLType* head,Data nodeData); //插入头结点 CLType *CLFindNode(CLType* head,char *key); //查找结点 CLType *CLInsetNode(CLType* head,char *findkey,Data nodeData);//插入结点 int CLDeleteNode(CLType* head,char *key); //删除结点 int CLLength(CLType* head); //计算链表长度 void CLAllNode(CLType *head); //遍历链表};#endif /* defined(__CHelloWorld__List__) */List.cpp
#include "List.h"CLType *List::CLAddEnd(CLType *head, Data nodeData){ CLType *node; CLType *htemp; if (!(node = (CLType*)malloc(sizeof(CLType)))) { cout<<"申请内存失败!"<<endl; return NULL; } else { node->nodeData = nodeData; node->nextNode = NULL; if (head == NULL) { head = node; return head; } htemp = head; while (htemp->nextNode != NULL) { htemp = htemp->nextNode; } htemp->nextNode = node; return head; }}CLType *List::CLAddFirst(CLType *head, Data nodeData){ CLType *node; if (!(node = (CLType*)malloc(sizeof(CLType)))) { cout<<"申请内存失败!"<<endl; return NULL; } else { node->nodeData = nodeData; node->nextNode = head; head = node; return head; }}CLType *List::CLFindNode(CLType *head, char *key){ CLType *htemp; htemp = head; while (htemp) { if (strcmp(htemp->nodeData.key, key) == 0) { return htemp; } htemp = htemp->nextNode; } return NULL;}CLType *List::CLInsetNode(CLType *head ,char *findkey, Data nodeData){ CLType *node,*nodetemp; if (!(node = (CLType*)malloc(sizeof(CLType)))) { cout<<"申请内存失败!"<<endl; return NULL; } node->nodeData = nodeData; nodetemp = CLFindNode(head, findkey); if (nodetemp) { node->nextNode = nodetemp->nextNode; nodetemp->nextNode = node; } else { cout<<"未找到正确的插入位置!"<<endl; free(node); } return head;}int List::CLDeleteNode(CLType *head, char *key){ CLType *node,*htemp; htemp = head; node = head; while (htemp) { if (strcmp(htemp->nodeData.key, key) == 0) { node->nextNode = htemp->nextNode; free(htemp); return 1; } else { node = htemp; htemp = htemp->nextNode; } } return 0;}int List::CLLength(CLType *head){ CLType *htemp; int Len = 0; htemp = head; while (htemp) { Len++; htemp = htemp->nextNode; } return Len;}void List::CLAllNode(CLType *head){ CLType *htemp; Data nodeData; htemp = head; printf("当前链共有%d个结点。链表所有数据如下:\n",CLLength(head)); while (htemp) { nodeData = htemp->nodeData; printf("结点(%s,%s,%d)\n",nodeData.key,nodeData.name,nodeData.age); htemp = htemp->nextNode; }}main.cpp
#include <iostream>#include "List.h"using namespace std;int main(int argc, const char * argv[]){ CLType *node,*head = NULL; Data nodeData; char key[10],findkey[10]; List *mylist = new List(); std::cout << "链表操作演示\n"; do { std::cout << "输入添加的结点(学号 姓名 年龄):"; fflush(stdin); //清空输入缓冲区 scanf("%s",nodeData.key); if (strcmp(nodeData.key, "0") == 0) //年龄不能为0 { break; } else { scanf("%s%d",nodeData.name,&nodeData.age); head = mylist->CLAddEnd(head,nodeData); } } while (1); mylist->CLAllNode(head); std::cout << "\n要插入结点:"; scanf("%s",&findkey); std::cout << "输入插入结点的数据(学号 姓名 年龄):\n"; scanf("%s%s%d",nodeData.key,nodeData.name,&nodeData.age); head = mylist->CLInsetNode(head, findkey, nodeData); mylist->CLAllNode(head); std::cout << "\n要删除结点:"; scanf("%s",key); mylist->CLDeleteNode(head, key); mylist->CLAllNode(head); std::cout << "\n演示在链表中查找,输入查找关键字:"; fflush(stdin); scanf("%s",key); node = mylist->CLFindNode(head, key); if (node) { nodeData = node->nodeData; scanf("关键字%s对应的结点为(%s,%s,%d)",key,nodeData.key,nodeData.name,&nodeData.age); } else { printf("在链表中未找到关键字为%s的结点!\n",key); } delete mylist; // insert code here... // std::cout << "Hello, World!\n"; return 0;}
演示效果图:
参考书籍:《C/C++常用算法手册》 《数据结构-清华大学严蔚敏》
- c/c++常用算法(2) -- 数据结构(线性表的链式存储)
- 线性表的链式存储C语言版
- C语言 数据结构 线性表 单链表 线性表的链式存储结构之一
- C语言数据结构-2.线性表之链式存储结构
- 数据结构(C语言) 线性表 链式存储 单链表
- 数据结构(C语言) 线性表 链式存储 双链表
- java常用数据结构---线性表---链式存储
- c/c++常用算法(1) -- 数据结构(线性表的顺序存储)
- 数据结构----纯C语言实现线性表的单向链式存储结构
- C - 数据结构 - 线性表 - 链式实现
- 数据结构 C语言实现 线性表的链式实现
- 数据结构之线性表的链式存储
- 【数据结构】线性表的链式存储结构
- 【数据结构】-线性表的链式存储结构
- 数据结构:线性表的链式存储
- 数据结构啊----线性表的链式存储
- 数据结构-线性表的链式存储
- 线性表的链式存储及相关操作 C语言版
- NSRunLoop(收藏)(转载)
- javascript中自定义类(1)
- 你听,寂寞在唱歌
- js 高效去除数组重复元素
- HTML5自学手册--HTML5 提供了播放音频的标准(5)
- c/c++常用算法(2) -- 数据结构(线性表的链式存储)
- 大数据挖掘算法篇之K-Means实例
- JavaScript中清空数组的三种方式
- freetype-2.5.2 compile with libpng support
- 课程分享Objective-C深入浅出,ios开发零基础入门(Xcode入门及语法入门)
- iOS_使用金山快盘管理项目
- Android模拟器上使用NIO编写客户端中,使用select超时,立马返回0的问题
- XMPPFramewok的使用
- javascript事件触发器fireEvent和dispatchEvent