C语言 线性表 顺序表结构 实现
一个能够自动扩容的顺序表 ArrList (GCC编译)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define TRUE 1
#define FALSE 0 typedef struct
{
int x;
int y;
}Point2D; // Point2D 结构 typedef struct
{
Point2D *pt; //线性表的数据项
int length; //线性表当前长度
int size; //线性表总容量
}ArrList; // ArrList 结构 //声明线性表所具有的方法
ArrList *CreateArrList( int nLength ); //创建长为 nArrLength 的线性表
void DestroyArrList( ArrList *pArrList ); //销毁线性表 pArrList
void ClearArrList( ArrList *pArrList ); //置空线性表 pArrList
int IsEmptyArrList( ArrList *pArrList ); //检测线性表是否为空
int GetArrListLength( ArrList *pArrList ); //获取线性表长度
int GetArrListSize( ArrList *pArrList ); //获取线性表总容量
int GetArrListElement( ArrList *pArrList, int n, Point2D *pt ); //获取线性表中第n个元素
int FindElement( ArrList *pArrList, int nPos, Point2D *pt ); //从 nPos 起查找 pt 第一次出现的位置
int GetPriorElement( ArrList *pArrList, Point2D *pt, Point2D *prior_pt ); //获取 pt 的前驱节点到 prior_pt
int GetNextElement( ArrList *pArrList, Point2D *pt, Point2D *next_pt ); //获取 pt 的后继节点到 next_pt
int AppendToArrList( ArrList *pArrList, Point2D *pt ); //将 pt 添加到线性表末尾处
int InsertToArrList( ArrList *pArrList, int nPos, Point2D *pt ); //将 pt 插入到 nPos 处
int DeleteFromArrList( ArrList *pArrList, int nPos ); //删除线性表上位置为 nPos 的元素
void ForEachArrList( ArrList *pArrList, void (*func)(Point2D *pt) ); //对线性表中每个元素执行 func 函数
int ArrListCpy( ArrList *pArrListDest, ArrList *pArrListSrc ); //将线性表 pArrListSrc 复制到 pArrListDest
int ArrListCat( ArrList *pArrListDest, ArrList *pArrListSrc ); //将线性表 pArrListSrc 连接到 pArrListDest 的末尾 //线性表方法实现
/**
* @brief 创建长度为 nLength 的线性表 ArrList
*
* @param nLength 所要构建的线性表长度
*
* @return 指向所创建的线性表的指针
*/
ArrList *CreateArrList( int nLength )
{
ArrList *pl = (ArrList *)malloc( sizeof(ArrList) ); pl->pt = (Point2D *)calloc( nLength, sizeof(Point2D) );
pl->length = ;
pl->size = nLength; return pl;
} /**
* @brief 销毁一条线性表
*
* @param pArrList 指向待销毁线性表的指针
*
* @return void
*/
void DestroyArrList( ArrList *pArrList )
{
free( pArrList->pt ); ///先释放线性表pt
free( pArrList ); ///销毁线性表pArrList
} /**
* @brief 置空一条线性表
*
* @param pArrList 指向待置空线性表的指针
*
* @return void
*/
void ClearArrList( ArrList *pArrList )
{
pArrList->length = ;
} /**
* @brief 检测线性表是否为空
*
* @param pArrList 指向待检测线性表的指针
*
* @return 为空则返回 TRUE, 否则返回 FALSE
*/
int IsEmptyArrList( ArrList *pArrList )
{
return pArrList->length == ? TRUE : FALSE;
} /**
* @brief 获取线性表长度
*
* @param pArrList 指向待获取长度的线性表的指针
*
* @return 返回获取到的线性表长度
*/
int GetArrListLength( ArrList *pArrList )
{
return pArrList->length;
} /**
* @brief 获取线性表总容量
*
* @param pArrList 指向待获取容量的线性表的指针
*
* @return 返回获取到的线性表的总容量
*/
int GetArrListSize( ArrList *pArrList )
{
return pArrList->size;
} /**
* @brief 获取线性表中第 n 个元素
*
* @param pArrList 指向待获取其中的元素的线性表的指针
* @param n 要获取的第 n 个元素
* @param pt 用于存放获取到的元素的值的 Point2D 类型指针
*
* @return 获取成功返回 TRUE, 否则返回 FALSE
*
* @note 元素n, n 从 0 起
*/
int GetArrListElement( ArrList *pArrList, int n, Point2D *pt )
{
if( n < || n > pArrList->length- )
return FALSE; pt->x = pArrList->pt[n].x;
pt->y = pArrList->pt[n].y; return TRUE;
} /**
* @brief 从 nPos 处查找元素 pt 第一次出现的位置
*
* @param pArrList 指向待查找其中的元素的线性表的指针
* @param nPos 查找起始位置
* @param pt 指向待查找元素的指针
*
* @return 若找到, 返回元素 pt 在线性表中的位置(下标), 否则返回 -1
*
* @note 位置从 0 计起
*/
int FindElement( ArrList *pArrList, int nPos, Point2D *pt )
{
int n = nPos;
for( n; n < pArrList->length; ++n )
{
if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
return n;
} return -;
} /**
* @brief 获取线性表中 pt 元素的前驱节点到 prior_pt
*
* @param pArrList 指向待获取其中的元素的线性表的指针
* @param pt 指向目标节点的指针
* @param prior_pt 存放查找到的目标节点的前驱节点
*
* @return 若获取到前驱节点, 返回目标节点的前驱节点在线性表中的位置(下标), 否则返回 -1
*
* @note 位置从 0 计起
*/
int GetPriorElement( ArrList *pArrList, Point2D *pt, Point2D *prior_pt )
{
int n = ;
for( n = ; n < pArrList->length; ++n )
{
if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
{
if( n <= ) ///目标节点是头节点, 无前驱节点
return -;
else ///存在并找到前驱节点
{
prior_pt->x = pArrList->pt[n-].x;
prior_pt->y = pArrList->pt[n-].y; return n-;
}
}
} return -;
} /**
* @brief 获取线性表中 pt 元素的后继节点到 next_pt
*
* @param pArrList 指向待获取其中的元素的线性表的指针
* @param pt 指向目标节点的指针
* @param next_pt 存放查找到的目标节点的后继节点
*
* @return 若获取到后继节点, 返回目标节点的后继节点在线性表中的位置(下标), 否则返回 -1
*
* @note 位置从 0 计起
*/
int GetNextElement( ArrList *pArrList, Point2D *pt, Point2D *next_pt )
{
int n = ;
for( n = ; n < pArrList->length; ++n )
{
if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
{
if( n >= pArrList->length- ) ///目标节点是尾节点, 无后继节点
return -;
else ///存在并找到后继节点
{
next_pt->x = pArrList->pt[n+].x;
next_pt->y = pArrList->pt[n+].y; return n+;
}
}
} return -;
} /**
* @brief 添加一个元素至线性表末尾
*
* @param pArrList 指向待添加元素的线性表的指针
* @param pt 指向待添加的元素的指针
*
* @return 成功添加则返回当前线性表长度, 否则返回 -1
*/
int AppendToArrList( ArrList *pArrList, Point2D *pt )
{
if( pArrList->size - pArrList->length < ) ///检测是否需要扩容
{
Point2D *p = (Point2D *)calloc(pArrList->length * , sizeof(Point2D));
memcpy( p, pArrList->pt, pArrList->length*sizeof(Point2D) );
pArrList->size = pArrList->length * ;
free( pArrList->pt );
pArrList->pt = p;
} pArrList->pt[pArrList->length].x = pt->x;
pArrList->pt[pArrList->length].y = pt->y; return ++pArrList->length;
} /**
* @brief 插入一个元素 pt 到线性表 nPos 处
*
* @param pArrList 指向待插入元素的线性表指针
* @param nPos 插入的位置(下标)
* @param pt 指向待插入的元素的指针
*
* @return 插入成功则返回当前线性表长度, 否则返回 -1
*
* @note 插入位置 nPos 从 0 计起
*/
int InsertToArrList( ArrList *pArrList, int nPos, Point2D *pt )
{
if( (nPos < ) || (nPos > pArrList->length-) )
return -; if( pArrList->size - pArrList->length < ) ///检测是否需要扩容
{
Point2D *p = (Point2D *)calloc(pArrList->length*, sizeof(Point2D));
memcpy( p, pArrList->pt, pArrList->length * sizeof(Point2D) );
pArrList->size = pArrList->length * ;
free( pArrList->pt );
pArrList->pt = p;
} int nMax = pArrList->length; ///获取线性表插入1元素后的长度
for( nMax; nMax > nPos; --nMax )
{
pArrList->pt[nMax].x = pArrList->pt[nMax-].x;
pArrList->pt[nMax].y = pArrList->pt[nMax-].y;
}
pArrList->pt[nPos].x = pt->x;
pArrList->pt[nPos].y = pt->y; return ++pArrList->length;
} /**
* @brief 从线性表上删除一个元素
*
* @param pArrList 指向待处理线性表的指针
* @param nPos 需要删除的元素位置(下标)
*
* @return 成功删除返回删除后线性表长度, 否则返回 -1
*
* @note 删除位置 nPos 从 0 计起
*/
int DeleteFromArrList( ArrList *pArrList, int nPos )
{
if( (nPos < ) || (nPos > pArrList->length - ) )
return -; if( nPos == pArrList->length - )
return --pArrList->length; for( nPos; nPos < pArrList->length; ++nPos )
{
pArrList->pt[nPos].x = pArrList->pt[nPos+].x;
pArrList->pt[nPos].y = pArrList->pt[nPos+].y;
} return --pArrList->length;
} /**
* @brief 对线性表中的元素依次执行传入的函数
*
* @param pArrList 指向待处理的线性表的指针
* @param func 传入的函数指针
*
* @return void
*
* @note 传入的函数的参数为线性表元素类型的指针
*/
void ForEachArrList( ArrList *pArrList, void (*func)(Point2D *pt) )
{
int i = ;
for( i = ; i < pArrList->length; ++i )
{
func( &pArrList->pt[i] );
}
} /**
* @brief 将线性表 pArrListSrc 复制到目标线性表 pArrListDest
*
* @param pArrListDest 目标线性表
* @param pArrListSrc 源线性表
*
* @return 成功则返回复制后的目标线性表的长度, 否则返回 -1
*/
int ArrListCpy( ArrList *pArrListDest, ArrList *pArrListSrc )
{
if( pArrListDest->size - pArrListSrc->length < ) ///目标线性表是否需要扩容
{
free(pArrListDest->pt);
Point2D *p = (Point2D *)calloc(pArrListSrc->length, sizeof(Point2D));
pArrListDest->pt = p;
pArrListDest->size = pArrListSrc->length;
} memcpy( pArrListDest->pt, pArrListSrc->pt, pArrListSrc->length * sizeof(Point2D) );
pArrListDest->length = pArrListSrc->length; return pArrListDest->length;
} /**
* @brief 将线性表 pArrListSrc 连接到目标线性表 pArrListDest
*
* @param pArrListDest 目标线性表
* @param pArrListSrc 源线性表
*
* @return 成功则返回连接后的目标线性表的长度, 否则返回 -1
*/
int ArrListCat( ArrList *pArrListDest, ArrList *pArrListSrc )
{
if( pArrListDest->size - pArrListDest->length < pArrListSrc->length ) ///目标线性表是否需要扩容
{
Point2D *p = (Point2D *)calloc(pArrListDest->length + pArrListSrc->length, sizeof(Point2D));
memcpy( p, pArrListDest->pt, pArrListDest->length * sizeof(Point2D) );
free(pArrListDest->pt);
pArrListDest->pt = p;
pArrListDest->size = pArrListDest->length + pArrListSrc->length;
} int pos = ;
for(pos; pos < pArrListSrc->length; ++pos )
{
pArrListDest->pt[pArrListDest->length + pos].x = pArrListSrc->pt[pos].x;
pArrListDest->pt[pArrListDest->length + pos].y = pArrListSrc->pt[pos].y;
} pArrListDest->length += pArrListSrc->length; return pArrListDest->length;
} //测试线性表 ArrList //回调函数
void display( Point2D *pt )
{
printf( "(%d,%d) ", pt->x, pt->y );
} int main()
{
Point2D pt1, pt2;
ArrList *plstA = CreateArrList( ); //创建一个长度为 10 的线性表 plstA ///
printf("测试添加元素..\n");
int i = ;
for( i; i < ; ++i )
{
pt1.x = i; pt1.y = i;
AppendToArrList( plstA, &pt1 ); //测试添加
}
ForEachArrList( plstA, display ); //对每个元素执行 display
printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试被动扩容添加..\n");
for( i = ; i < ; ++i )
{
pt1.x = i; pt1.y = i;
AppendToArrList( plstA, &pt1 ); //测试被动扩容
}
ForEachArrList( plstA, display );
printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试插入到头部、尾部..\n");
pt1.x = ; pt1.y = ;
InsertToArrList( plstA, , &pt1 ); //测试插入到首部
InsertToArrList( plstA, GetArrListLength(plstA)-, &pt1 ); //测试插入到尾部
ForEachArrList( plstA, display );
printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试获取节点元素..\n");
GetArrListElement( plstA, , &pt2 ); //获取节点位置为5的元素
printf("节点坐标为5的元素pt2: (%d,%d)\n", pt2.x, pt2.y); ///
printf("\n测试获取某元素的前驱节点..\n");
Point2D pri_pt, next_pt;
GetPriorElement( plstA, &pt2, &pri_pt ); //获取 pt2 的前驱节点
printf("pt2的前驱节点: (%d, %d)\n", pri_pt.x, pri_pt.y);
GetNextElement( plstA, &pt2, &next_pt ); //获取 pt2 的后继节点
printf("pt2的后继节点: (%d, %d)\n", next_pt.x, next_pt.y); ///
printf("\n测试查找元素..\n");
printf("元素 next_pt 在线性表中第一次出现的位置: %d\n", FindElement(plstA, , &next_pt)); //从 0 起查找元素 next_pt ///
printf("\n测试删除某元素..\n");
printf("删除位置为0的元素: ");
DeleteFromArrList( plstA, ); //删除节点位置为0的元素
ForEachArrList( plstA, display );
printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试复制线性表..\n");
printf("创建线性表 plstB : ");
ArrList *plstB = CreateArrList( );
for( i = ; i < ; ++i )
{
pt2.x = i; pt2.y = i;
AppendToArrList( plstB, &pt2 );
}
ForEachArrList( plstB, display );
printf( "\nplstB len = %d, size = %d\n", GetArrListLength(plstB), GetArrListSize(plstB) );
printf("将 plstB 复制到 plstA: \n");
ArrListCpy( plstA, plstB ); //将线性表 plstB 复制到 plstA
ForEachArrList( plstA, display );
printf( "plstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试连接线性表..\n");
printf("将 plstB 连接到 plstA: ");
ArrListCat( plstA, plstB ); //将线性表 plstB 连接到 plstA
ForEachArrList( plstA, display );
printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) ); ///
printf("\n测试清空线性表..\n");
ClearArrList( plstA ); //清空线性表 plstA
ForEachArrList( plstA, display );
printf( "plstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
printf( "IsEmpty = %d\n", IsEmptyArrList(plstA) ); ///
printf("\n销毁线性表..\n");
DestroyArrList( plstA ); //销毁线性表, 释放资源
DestroyArrList( plstB ); return ;
}
若存在 bug 或程序缺陷, 请留言反馈, 谢谢。
C语言 线性表 顺序表结构 实现的更多相关文章
- 数据结构C语言版--动态顺序表的基本功能实现(二)
/* * 若各个方法结构体变量参数为: &L(即地址符加变量)则结构体变量访问结构成员变量时使用"." * 若为:*L(即取地址符加变量)则结构体变量访问结构体成员变量使用 ...
- 【数据结构】线性表&&顺序表详解和代码实例
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 预备知识 1.0 什么是线性表? 线性表(List)是零个或者多个数据元素的有限序列. 首先它是一个序列.里面的元素是有顺 ...
- C语言实现的顺序表
顺序表是用一段地址连续的存储单元依次存储数据元素的线性结构.顺序表可分为静态存储和动态存储,静态顺序表比较简单,数据空间固定,而动态顺序表可以动态增容,便于存放大量数据,现主要把动态的基本实现一下~此 ...
- 线性表——顺序表的实现与讲解(C++描述)
线性表 引言 新生安排体检,为了 便管理与统一数据,学校特地规定了排队的方式,即按照学号排队,谁在前谁在后,这都是规定好的,所以谁在谁不在,都是非常方便统计的,同学们就像被一条线(学号)联系起来了,这 ...
- JAVA实现具有迭代器的线性表(顺序表)
1,先了解下JAVA类库中的迭代器:JAVA提供了两种基本类型的迭代器,分别用两个接口来表示:Iterator<T>,ListIterator<T>.其中,Iterator&l ...
- C语言项目实现顺序表
#include <stdio.h> #include <stdlib.h> #include "test_顺序表声明.h" /* run this pro ...
- C语言学习笔记-顺序表
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include "coni ...
- C语言版本:顺序表的实现
seqlist.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include<cstdio> #include<malloc.h> ...
- c语言描述的顺序表实现
//顺序表的实现:(分配一段连续地址给顺序表,像数组一样去操作) #include<stdio.h> #include<stdlib.h> #define OK 1 #defi ...
随机推荐
- Log4Net日志的配置
<configuration> <configSections> <section name="log4net" type="log ...
- Java项目导出war包 security alert:integrity check error”
操作方法: 首先下载这个jar包 http://pan.baidu.com/s/1sk5uDzf 1.需要先把common/pluns 下的com.genuitec.eclipse.export.wi ...
- MySQL_杭州11月销售昨日未上架的SKU_20161212
#C034杭州11月销售昨日未上架的SKU SELECT 城市,a.订单日期,a.客户数,a.订单数,b.产品数,a.金额,c.销售确认额,c.毛利额,c.毛利率 FROM ( SELECT 城市,订 ...
- js数组合并
// 第一种 var mergeTo = [4,5,6], mergeFrom = [7,8,9]; mergeTo = mergeTo.concat(mergeFrom); mergeTo; // ...
- sql基础知识(新手必备)
一.简单查询 1.查询所有数据,查询部分列数据,列别名 SELECT * FROM 表名 SELECT 列1 AS 'BIAOTI1','BIAOTI2'=列2 FROM 表名 2.查询不重复的数据 ...
- 在MS SQLSERVER中如何最快的速度清空所有用户表的数据
有时候我们需要清空数据库中所有用户表的数据,如果一张表一张表的清空的话,遇到一个庞大的数据系统估计得崩溃了. 用游标加上用变量来引用表名就可以做到这一点. 用变量来引用表名对表操作可以用在存储过程中 ...
- 【Tyvj1601】魔兽争霸(主席树,树套树)
题意:要求在N个数的序列中支持以下操作: 1:将第X个元素加上Y 2:询问当前K大值 n<=30000,m<=50000 思路:树状数组套主席树 Tyvj又炸了,还不知道对不对 ..12] ...
- JAVA中implements的用法
implements使用 interface Sport { void run(); void jump(); } class Athlete implements Sport { public vo ...
- iOS工作笔记(十三)
1.automaticallyAdjustsScrollViewInsets的使用 这是UIViewController的属性,设置为YES就是根据status bar,navigation bar, ...
- HttpURLConnection请求网络数据
//使用线程 new Thread(){ public void run() { try { //先创建出了一 ...