【数据结构】Liner-List 线性表(更新时间:2016-04-06)
来源:互联网 发布:飞鱼网络电视tv版 编辑:程序博客网 时间:2024/05/16 18:55
【数据结构】Liner-List 线性表(更新时间:2016-04-06)
趁着室友刚刚开始学习数据结构,赶紧配合着他的进度来写关于数据结构的相关内容
博文中的代码均使用C++语法,部分代码(主要是函数重载等)无法在C语言环境下编译
线性表 是最简单、最基本也是最常用的数据结构,它是以数组为基础定义的使得所需要的 元素 和 存储空间 一一对应的一种数据结构,即每一个存储元素都对应于一个特定的存储位置。
常见的线性表是用数组来存储,也就是我们常说的顺序存储:
struct ListNode; //定义线性表表头节点typedef ListNode* PtrToNode; //定义线性表表头指针typedef PtrToNode LinerList; //重定义表头指针typedef int ElementType; //重定义数据类型struct ListNode //数据结构描述{ int capacity; //表的容量 int tail; //指向当前表的尾部 ElementType* Element; //数据域};const int MAX_CAP = 100; //初始容量
示意图:
基础操作
初始化
将线性表初始化,通过指针操作,将表头地址传入初始化函数,并以指针的形式返回表头。初始化表的容量以及表的尾指针。
LinerList Initial( void ) //表的初始化{ LinerList L = NULL; L = ( LinerList ) malloc ( sizeof(ListNode) ); //分配表头地址 L->capacity = MAX_CAP; //初始化数值域空间 L->tail = 0; //表尾部指针指向表头 L->Element = ( ElementType* ) malloc( L->capacity * sizeof( ElementType ) ); //分配数值域地址 return L; //返回表头}
删除表
将整个线性表删除,表头置为空指针
void Delete( LinerList L ) //表的删除{ if( L != NULL ) { free( L->Element ); //释放数值域空间 free( L ); //释放表头 L = NULL; //表头置空 }}
扩充表
在我们向线性表中插入数据的时候,由于线性表的有限性,会出现线性表容量溢出的情况,在这种情况下,我们可以使用realloc
函数来达到重新分配数值空间的目的。
LinerList Expansion( LinerList L ) //表的扩容{ L->capacity++; //容量扩充 L->Element = ( ElementType* ) realloc ( L->Element, L->capacity * sizeof( ElementType ) ); //重分配数据空间}
查找
对于线性表,我们经常需要查询其中是否存在某特定的元素。
int Find( const LinerList L, const ElementType X ) //查找元素{ int pos = 0; //游标初始化 while( L->Element[pos] != X && pos < L->tail ) //游标遍历搜索 pos++; if( pos != L->tail ) //如果找到返回pos return pos; else return 0;}
插入元素
对于线性表的插入主要分为简单插入和定点插入两种(使用函数重载来进行插入类别的判断):
简单插入 是指直接在表的尾部插入元素,如果表已满,则对表进行扩容。
LinerList Insert( LinerList L, const ElementType X ) //简单插入{ if( L->tail == L->capacity ) //判断是否过载 Expansion( L ); //扩容 L->Element[ L->tail++ ] = X; //插入 return L; //返回表头}
定点插入 是指插入位置与表的容量和表尾的相对状况进行插入,当插入位置在表尾内,则插入元素,如果插入位置非法,则返回原表。
LinerList Insert( LinerList L, const ElementType X, const int Pos ) //定点插入{ int p = L->tail; //游标指向表尾 if( Pos > L->tail ) //判断插入位置合法性 { cout << "Wrong insert position!\n"; return L; } if( L->tail == L->capacity ) //判断是否过载 { Expansion( L ); L->tail++; } for( ; p > Pos; p-- ) //将数值逐个后移 L->Element[p+1] = L->Element[p]; L->Element[p] = X; //插入}
删除元素
在线性表的使用过程中,除了插入一些元素之外,我们还需要删除一些元素。删除顺序线性表的方法是使用后面的元素填充到前面的元素之中。插入也分为简单删除和定点删除。由于代码中的Element类型为int,故暂时无法使用函数重载来在同一个代码区实现。
简单删除 调用代码中的Find
函数来查找所要删除的元素是否出现在表中,如果出现则删除。
LinerList Delete( LinerList L, const ElementType X ) //简单删除{ int pos = Find( L, X ); //游标初始化 if( !pos ) //未找到指定元素 { cout << X << " is not found in the LinerList!\n"; return L; } else { L->tail--; //尾表前移 while( pos < L->tail ) //元素逐个前移 L->Element[pos] = L->Element[pos+1]; return L; }}
定点删除 同定点插入。
LinerList Delete( LinerList L, const int Pos ) //定点删除{ int p = Pos; if( Pos > L->tail || Pos < 0 ) //判断是否越界 { cout << "Wrong deletion postion!\n"; return L; } L->tail--; //尾标前移 while( p < L->tail ) //元素逐个前移 L->Element[p] = L->Element[p+1]; return L;}
打印表
在使用线性表的时候我们会需要将表格打印出来,在这里简单示例用空格隔开每个元素。
void Print( const LinerList L ) //打印表{ int pos = 0; //游标初始化 if( L == NULL ) { cout << "Empty List!\n"; return; } while( pos < L->tail ) { cout << L->Element[pos] << ' '; //打印元素并添加空格 pos++; } cout << endl; //输出换行}
代码示例
注:其中的一个删除元素的函数被注释掉了,不体现实际功能
#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;/*********************************************************/struct ListNode; //定义线性表表头节点typedef ListNode* PtrToNode; //定义线性表表头指针typedef PtrToNode LinerList; //重定义表头指针typedef int ElementType; //重定义数据类型struct ListNode //数据结构描述{ int capacity; //表的容量 int tail; //指向当前表的尾部 ElementType* Element; //数据域};const int MAX_CAP = 100; //初始容量/*********************************************************/void Delete( LinerList L ); //表的删除LinerList Initial( void ); //表的初始化LinerList Expansion( LinerList L ); //表的扩充int Find( const LinerList L, const ElementType X ); //查找元素LinerList Insert( LinerList L, const ElementType X ); //简单插入LinerList Insert( LinerList L, const ElementType X, const int Pos ); //定点插入LinerList Delete( LinerList L, const ElementType X ); //简单删除LinerList Delete( LinerList L, const int Pos ); //定点删除void Print( const LinerList L ); //打印表/*********************************************************/int main(){ LinerList L; ElementType X; int i; L = Initial(); for( i = 0; i < MAX_CAP-1; i++ ) Insert( L, i ); Insert( L, 99 ); Insert( L, 100, 100 ); Print( L ); Insert( L, 101, 102 ); Delete( L, 103 ); Delete( L );}/*********************************************************/void Delete( LinerList L ) //表的删除{ free( L->Element ); //释放表的数值域空间 free( L ); //释放表头 L = NULL; //表头置空}LinerList Initial( void ) //表的初始化{ LinerList L = NULL; L = ( LinerList ) malloc ( sizeof(ListNode) ); //分配表头地址 L->capacity = MAX_CAP; //初始化数值域空间 L->tail = 0; //表尾部指针指向表头 L->Element = ( ElementType* ) malloc( L->capacity * sizeof( ElementType ) ); //分配数值域地址 return L; //返回表头}LinerList Expansion( LinerList L ) //表的扩容{ L->capacity++; //容量扩充 L->Element = ( ElementType* ) realloc ( L->Element, L->capacity * sizeof( ElementType ) ); //重分配数据空间}int Find( const LinerList L, const ElementType X ) //查找元素{ int pos = 0; //游标初始化 while( L->Element[pos] != X && pos < L->tail ) //游标遍历搜索 pos++; if( pos != L->tail ) //如果找到则返回pos return pos; else return 0;}LinerList Insert( LinerList L, const ElementType X ) //简单插入{ if( L->tail == L->capacity ) //判断是否过载 Expansion( L ); //扩容 L->Element[ L->tail++ ] = X; //插入 return L; //返回表头}LinerList Insert( LinerList L, const ElementType X, const int Pos ) //定点插入{ int p = L->tail; //游标指向表尾 if( Pos > L->tail ) //判断插入位置合法性 { cout << "Wrong insert position!\n"; return L; } if( L->tail == L->capacity ) //判断是否过载 { Expansion( L ); L->tail++; } for( ; p > Pos; p-- ) //将数值逐个后移 L->Element[p+1] = L->Element[p]; L->Element[p] = X; //插入}LinerList Delete( LinerList L, const ElementType X ) //简单删除{ int pos = Find( L, X ); //游标初始化 if( !pos ) //未找到指定元素 { cout << X << " is not found in the LinerList!\n"; return L; } else { L->tail--; //尾表前移 while( pos < L->tail ) //元素逐个前移 L->Element[pos] = L->Element[pos+1]; return L; }}/*LinerList Delete( LinerList L, const int Pos ) //定点删除{ int p = Pos; if( Pos > L->tail || Pos < 0 ) //判断是否越界 { cout << "Wrong deletion postion!\n"; return L; } L->tail--; //尾标前移 while( p < L->tail ) //元素逐个前移 L->Element[p] = L->Element[p+1]; return L;}*/void Print( const LinerList L ) //打印表{ int pos = 0; //游标初始化 if( L == NULL ) { cout << "Empty List!\n"; return; } while( pos < L->tail ) { cout << L->Element[pos] << ' '; //打印元素并添加空格 pos++; } cout << endl; //输出换行}
- 【数据结构】Liner-List 线性表(更新时间:2016-04-06)
- 【数据结构】Doubly-Linked List双向链表(更新时间:2016-04-13)
- 【数据结构】Orthogonal-List 十字链表(更新时间:2016-04-15)
- 【数据结构】Singly-Linked-List 单链表(更新时间:2016-04-07)
- 数据结构-线性表(List)1
- 【数据结构】线性表(Linear List)
- 【数据结构学习】线性表List
- C#数据结构--线性表--List
- 【数据结构】Stack 栈(更新时间:2016-04-13)
- 数据结构学习笔记---线性表LIST
- 数据结构_线性表顺序sequence List
- 数据结构(线性表)
- 数据结构(线性表)
- 数据结构(线性表)
- 数据结构(线性表)
- 机器学习入门 | 使用梯度下降(Gradient Descent)实现线性回归(Liner Regression)
- 【数据结构】FibonacciHeap 斐波那契堆(更新时间:2016-04-07)
- 线性表(List) 一
- jquery checkbox 全选反选 第一二次有反应下来点击无效果
- 利用WireShark破解网站密码
- 【bzoj1927】[Sdoi2010]星际竞速
- Android的WakeLock机制
- CSS中vh和vw单位设置宽高
- 【数据结构】Liner-List 线性表(更新时间:2016-04-06)
- Oracle Merge into 详细介绍
- myeclipse快捷键
- 更正给mongo3.x加上认证功能
- Linux C 堆与栈的区别
- Tab栏目切换效果
- caffe中对6种激活函数类的封装--Sigmod
- Spring整合JMS(二)——三种消息监听器
- Gardner定时恢复