数据结构(13)线性表
2015-08-10 19:41
645 查看
线性表是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。Balabala.....其实最简单的也就不用说了,上述是取自百度百科对于线性表的定义。而在这里,就简单说明下线性表的定义:
线性表是具有相同类型的n个数据元素的有限序列: (a1, a2, a3, a4, ......, an) ai是表项, n是表长度
或许大家应该能联想到数组,其实是和线性表是一个道理,性质如下:
1. a0为表首元素,只有一个后继
2. an为表尾元素,只有一个前驱
3. 除a0和an外的其他元素ai,既有前驱,又有后继
4. 线性表能够逐项访问和顺序存取
这里主要介绍线性表的常用操作:
l 创建线性表
l 销毁线性表
l 清空线性表
l 表元素插入
l 表元素删除
l 获取表中某个位置的元素
l 获取表长度
代码总分为三个文件:
SeqList.h : 放置功能函数的声明,以及表和表结点的声明
SeqList.h : 放置功能函数的定义,以及表和表结点的定义
Main.c : 主函数,使用功能函数完成各种需求,不过我一般是用作测试
用一副图来描述下代码的总体结构:
其实对于在SeqList.c 和SeqList.h文件中分别定义SeqList,我刚开始看的时候也不懂,在SeqList.c文件中每次使用函数参数中的list,需要强制类型转换为sList,后来才知道多了一次转换是为了更高的安全性和可靠性。
这里着重说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
首先判断线性表﹑插入位置是否合法,表是否已满
把最后一个元素到插入位置的元素向后移一个位置
把新元素插入
最后把线性表长度加1
删除操作:
如图
删除元素方法:
首先判断线性表﹑删除位置是否合法
把要删除的元素取出
然后从删除元素后一个位置的元素到最后元素依次往前移一个位置
最后把线性表长度减1
OK! 上代码:
SeqList.h
[cpp] view
plaincopy
#ifndef _SEQLIST_H_ //防止重复调用
#define _SEQLIST_H_
typedef void SeqList;
typedef void SeqListNode;
SeqList* SeqList_Create(int capacity);
void SeqList_Destroy(SeqList* list);
void SeqList_Clear(SeqList* list);
int SeqList_Length(SeqList* list);
int SeqList_Capacity(SeqList* list);
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
SeqListNode* SeqList_Get(SeqList* list, int pos);
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif
SeqList.c
[cpp] view
plaincopy
#include <stdio.h>
#include <malloc.h>
#include "SeqList.h"
typedef unsigned int TSeqListNode;
typedef struct _tag_SeqList
{
int capacity;
int length;
TSeqListNode* node;
}TSeqList;
SeqList* SeqList_Create(int capacity)
{
TSeqList* ret = NULL;
if(ret == NULL)
{
ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode)*capacity);
}
if(ret != NULL)
{
ret->capacity = capacity;
ret->length = 0;
ret->node = (TSeqListNode*)(ret+1);
}
return ret;
}
void SeqList_Destroy(SeqList* list)
{
free(list);
}
void SeqList_Clear(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
if(sList!=NULL)
{
sList->length = 0;
}
}
int SeqList_Length(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->length;
}
return ret;
}
int SeqList_Capacity(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->capacity;
}
return ret;
}
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
TSeqList* sList = (TSeqList*)list;
int ret = (sList!=NULL);
int i = 0;
ret = ret && (sList->length+1 <= sList->capacity);
ret = ret && (pos >= 0);
if(ret)
{
if(pos >= sList->length)
{
pos = sList->length;
}
for(i=sList->length; i>pos; i--)
{
sList->node[i] = sList->node[i-1];
}
sList->node[i] = (TSeqListNode)node;
sList->length++;
}
return ret;
}
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
TSeqList* sList = (TSeqList*)list;
SeqListNode* ret = NULL;
if( (sList!=NULL) && (pos >= 0) && (pos<sList->length) )
{
ret = (TSeqListNode*)(sList->node[pos]);
}
return ret;
}
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
SeqListNode* ret = SeqList_Get(list, pos);
TSeqList* sList = (TSeqList*)list;
int i = 0;
if(ret!=NULL)
{
for(i=pos+1; i<sList->length; i++)
{
sList->node[i-1] = sList->node[i];
}
sList->length--;
}
return ret;
}
main.c
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
int main(void)
{
SeqList* list = SeqList_Create(6);
int i=0, j=1, k=2;
int x=3, y=4, z=5;
int index = 0;
SeqList_Insert(list, &i, 0);
SeqList_Insert(list, &j, 0);
SeqList_Insert(list, &k, 0);
SeqList_Insert(list, &x, 0);
SeqList_Insert(list, &y, 0);
SeqList_Insert(list, &z, 0);
for(index=0; index<SeqList_Length(list); index++)
{
int* p = (int*)SeqList_Get(list, index);
printf("%d\n", *p);
}
while(SeqList_Length(list) > 0)
{
int* p = (int*)SeqList_Delete(list, 0);
printf("%d\n", *p);
}
SeqList_Destroy(list);
return 0;
}
本文借鉴:http://blog.csdn.net/nethanhan/article/details/9670577
线性表是具有相同类型的n个数据元素的有限序列: (a1, a2, a3, a4, ......, an) ai是表项, n是表长度
或许大家应该能联想到数组,其实是和线性表是一个道理,性质如下:
1. a0为表首元素,只有一个后继
2. an为表尾元素,只有一个前驱
3. 除a0和an外的其他元素ai,既有前驱,又有后继
4. 线性表能够逐项访问和顺序存取
这里主要介绍线性表的常用操作:
l 创建线性表
l 销毁线性表
l 清空线性表
l 表元素插入
l 表元素删除
l 获取表中某个位置的元素
l 获取表长度
代码总分为三个文件:
SeqList.h : 放置功能函数的声明,以及表和表结点的声明
SeqList.h : 放置功能函数的定义,以及表和表结点的定义
Main.c : 主函数,使用功能函数完成各种需求,不过我一般是用作测试
用一副图来描述下代码的总体结构:
其实对于在SeqList.c 和SeqList.h文件中分别定义SeqList,我刚开始看的时候也不懂,在SeqList.c文件中每次使用函数参数中的list,需要强制类型转换为sList,后来才知道多了一次转换是为了更高的安全性和可靠性。
这里着重说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
首先判断线性表﹑插入位置是否合法,表是否已满
把最后一个元素到插入位置的元素向后移一个位置
把新元素插入
最后把线性表长度加1
删除操作:
如图
删除元素方法:
首先判断线性表﹑删除位置是否合法
把要删除的元素取出
然后从删除元素后一个位置的元素到最后元素依次往前移一个位置
最后把线性表长度减1
OK! 上代码:
SeqList.h
[cpp] view
plaincopy
#ifndef _SEQLIST_H_ //防止重复调用
#define _SEQLIST_H_
typedef void SeqList;
typedef void SeqListNode;
SeqList* SeqList_Create(int capacity);
void SeqList_Destroy(SeqList* list);
void SeqList_Clear(SeqList* list);
int SeqList_Length(SeqList* list);
int SeqList_Capacity(SeqList* list);
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
SeqListNode* SeqList_Get(SeqList* list, int pos);
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif
SeqList.c
[cpp] view
plaincopy
#include <stdio.h>
#include <malloc.h>
#include "SeqList.h"
typedef unsigned int TSeqListNode;
typedef struct _tag_SeqList
{
int capacity;
int length;
TSeqListNode* node;
}TSeqList;
SeqList* SeqList_Create(int capacity)
{
TSeqList* ret = NULL;
if(ret == NULL)
{
ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode)*capacity);
}
if(ret != NULL)
{
ret->capacity = capacity;
ret->length = 0;
ret->node = (TSeqListNode*)(ret+1);
}
return ret;
}
void SeqList_Destroy(SeqList* list)
{
free(list);
}
void SeqList_Clear(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
if(sList!=NULL)
{
sList->length = 0;
}
}
int SeqList_Length(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->length;
}
return ret;
}
int SeqList_Capacity(SeqList* list)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->capacity;
}
return ret;
}
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
TSeqList* sList = (TSeqList*)list;
int ret = (sList!=NULL);
int i = 0;
ret = ret && (sList->length+1 <= sList->capacity);
ret = ret && (pos >= 0);
if(ret)
{
if(pos >= sList->length)
{
pos = sList->length;
}
for(i=sList->length; i>pos; i--)
{
sList->node[i] = sList->node[i-1];
}
sList->node[i] = (TSeqListNode)node;
sList->length++;
}
return ret;
}
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
TSeqList* sList = (TSeqList*)list;
SeqListNode* ret = NULL;
if( (sList!=NULL) && (pos >= 0) && (pos<sList->length) )
{
ret = (TSeqListNode*)(sList->node[pos]);
}
return ret;
}
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
SeqListNode* ret = SeqList_Get(list, pos);
TSeqList* sList = (TSeqList*)list;
int i = 0;
if(ret!=NULL)
{
for(i=pos+1; i<sList->length; i++)
{
sList->node[i-1] = sList->node[i];
}
sList->length--;
}
return ret;
}
main.c
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
int main(void)
{
SeqList* list = SeqList_Create(6);
int i=0, j=1, k=2;
int x=3, y=4, z=5;
int index = 0;
SeqList_Insert(list, &i, 0);
SeqList_Insert(list, &j, 0);
SeqList_Insert(list, &k, 0);
SeqList_Insert(list, &x, 0);
SeqList_Insert(list, &y, 0);
SeqList_Insert(list, &z, 0);
for(index=0; index<SeqList_Length(list); index++)
{
int* p = (int*)SeqList_Get(list, index);
printf("%d\n", *p);
}
while(SeqList_Length(list) > 0)
{
int* p = (int*)SeqList_Delete(list, 0);
printf("%d\n", *p);
}
SeqList_Destroy(list);
return 0;
}
本文借鉴:http://blog.csdn.net/nethanhan/article/details/9670577
相关文章推荐
- 【暑假】[实用数据结构]前缀树 Trie
- 可视化的数据结构和算法
- MySQL索引背后的数据结构及算法原理
- 数据结构(12)哈希表
- 数据结构(11)无向图相关算法基础
- 数据结构(9)平衡查找树之B树
- 数据结构(8)平衡查找树之红黑树
- 数据结构(7)平衡查找树之2-3树
- 数据结构(6)二叉树
- 数据结构(5)优先级队列与堆排序
- B-tree B+tree 数据结构解析
- 数据结构(4)快速排序
- C源码@数据结构与算法->基数排序
- 数据结构(3)合并排序
- 数据结构(2)基本排序算法
- 程序员必须知道的10个算法和数据结构有哪些?
- 【数据结构与算法】折半查找算法(二分法)
- 数据结构上机实验之二分查找
- 【暑假专题训练#数据结构】
- 数据结构学习笔记3-字符串转换成整数