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 ...
随机推荐
- CentOS6 搭建Git仓库
近期上了Redmine以后,系统集成了Git的联动功能,于是萌生了搭建内网仓库的想法,特此记录一下: 1.安装Git yum -y install git 2.创建用户及密码 useradd git ...
- spark Mllib基本功系列编程入门之 SVM实现分类
话不多说.直接上代码咯.欢迎交流. /** * Created by whuscalaman on 1/7/16. */import org.apache.spark.{SparkConf, Spar ...
- {CSDN}{英雄会}{反相互}
思路: 给定一个字符串,求两个不重叠的字串,他们翻转互补.其中一个字符串可以是删掉最多两个字符的原字符串子串. 动态规划,由于可以对子串进行删除操作,我首先想到了LCS问题,但需要枚举所有的长度,这样 ...
- Style file: generic.xaml
All silverlight control style should be designed in generic.xaml which is in theme folder. But when ...
- vnc
Xvnc, Xvnc-core, vncagent, vncinitconfig, vnclicense, vnclicensehelper, vnclicensewiz, vncpasswd, vn ...
- Bias and Variance
以下内容参考 cousera 吴恩达 机器学习课程 1. Bias 和 Variance 的定义 Bias and Variance 对于改进算法具有很大的帮助作用,在bias和Variance的指引 ...
- 【POJ2949】Word Rings(最大平均值环)
题意:给定N个字符串,如果A串的最后两个字母跟B串的前两个字母相同它们就能连接. 求一个由字符串组成的首尾相连的环,使(字符串总长度/字符串个数)最大. n<=100000 len<=10 ...
- Python随机森林算法的使用
#coding:utf-8 # from python.Lib.packages.sklearn.tree import DecisionTreeClassifier # from python.Li ...
- Springmvc4 com/fasterxml/jackson/core/JsonProcessingException
非常感谢: 谭卓博客 springmvc4 json springmvc4 集成hibernate4 出现 NoClassDefFoundError:com/fasterxml/jackson/cor ...
- WINDOWS的NTP配置
将下面内容复制到记事本,保存成ntp.bat net stop w32Time REG ADD HKLM\SYSTEM\CurrentControlSet\Services\W32Time\TimeP ...