一个能够自动扩容的顺序表 ArrList (GCC编译)。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define TRUE 1
  6. #define FALSE 0
  7.  
  8. typedef struct
  9. {
  10. int x;
  11. int y;
  12. }Point2D; // Point2D 结构
  13.  
  14. typedef struct
  15. {
  16. Point2D *pt; //线性表的数据项
  17. int length; //线性表当前长度
  18. int size; //线性表总容量
  19. }ArrList; // ArrList 结构
  20.  
  21. //声明线性表所具有的方法
  22. ArrList *CreateArrList( int nLength ); //创建长为 nArrLength 的线性表
  23. void DestroyArrList( ArrList *pArrList ); //销毁线性表 pArrList
  24. void ClearArrList( ArrList *pArrList ); //置空线性表 pArrList
  25. int IsEmptyArrList( ArrList *pArrList ); //检测线性表是否为空
  26. int GetArrListLength( ArrList *pArrList ); //获取线性表长度
  27. int GetArrListSize( ArrList *pArrList ); //获取线性表总容量
  28. int GetArrListElement( ArrList *pArrList, int n, Point2D *pt ); //获取线性表中第n个元素
  29. int FindElement( ArrList *pArrList, int nPos, Point2D *pt ); //从 nPos 起查找 pt 第一次出现的位置
  30. int GetPriorElement( ArrList *pArrList, Point2D *pt, Point2D *prior_pt ); //获取 pt 的前驱节点到 prior_pt
  31. int GetNextElement( ArrList *pArrList, Point2D *pt, Point2D *next_pt ); //获取 pt 的后继节点到 next_pt
  32. int AppendToArrList( ArrList *pArrList, Point2D *pt ); //将 pt 添加到线性表末尾处
  33. int InsertToArrList( ArrList *pArrList, int nPos, Point2D *pt ); //将 pt 插入到 nPos 处
  34. int DeleteFromArrList( ArrList *pArrList, int nPos ); //删除线性表上位置为 nPos 的元素
  35. void ForEachArrList( ArrList *pArrList, void (*func)(Point2D *pt) ); //对线性表中每个元素执行 func 函数
  36. int ArrListCpy( ArrList *pArrListDest, ArrList *pArrListSrc ); //将线性表 pArrListSrc 复制到 pArrListDest
  37. int ArrListCat( ArrList *pArrListDest, ArrList *pArrListSrc ); //将线性表 pArrListSrc 连接到 pArrListDest 的末尾
  38.  
  39. //线性表方法实现
  40. /**
  41. * @brief 创建长度为 nLength 的线性表 ArrList
  42. *
  43. * @param nLength 所要构建的线性表长度
  44. *
  45. * @return 指向所创建的线性表的指针
  46. */
  47. ArrList *CreateArrList( int nLength )
  48. {
  49. ArrList *pl = (ArrList *)malloc( sizeof(ArrList) );
  50.  
  51. pl->pt = (Point2D *)calloc( nLength, sizeof(Point2D) );
  52. pl->length = ;
  53. pl->size = nLength;
  54.  
  55. return pl;
  56. }
  57.  
  58. /**
  59. * @brief 销毁一条线性表
  60. *
  61. * @param pArrList 指向待销毁线性表的指针
  62. *
  63. * @return void
  64. */
  65. void DestroyArrList( ArrList *pArrList )
  66. {
  67. free( pArrList->pt ); ///先释放线性表pt
  68. free( pArrList ); ///销毁线性表pArrList
  69. }
  70.  
  71. /**
  72. * @brief 置空一条线性表
  73. *
  74. * @param pArrList 指向待置空线性表的指针
  75. *
  76. * @return void
  77. */
  78. void ClearArrList( ArrList *pArrList )
  79. {
  80. pArrList->length = ;
  81. }
  82.  
  83. /**
  84. * @brief 检测线性表是否为空
  85. *
  86. * @param pArrList 指向待检测线性表的指针
  87. *
  88. * @return 为空则返回 TRUE, 否则返回 FALSE
  89. */
  90. int IsEmptyArrList( ArrList *pArrList )
  91. {
  92. return pArrList->length == ? TRUE : FALSE;
  93. }
  94.  
  95. /**
  96. * @brief 获取线性表长度
  97. *
  98. * @param pArrList 指向待获取长度的线性表的指针
  99. *
  100. * @return 返回获取到的线性表长度
  101. */
  102. int GetArrListLength( ArrList *pArrList )
  103. {
  104. return pArrList->length;
  105. }
  106.  
  107. /**
  108. * @brief 获取线性表总容量
  109. *
  110. * @param pArrList 指向待获取容量的线性表的指针
  111. *
  112. * @return 返回获取到的线性表的总容量
  113. */
  114. int GetArrListSize( ArrList *pArrList )
  115. {
  116. return pArrList->size;
  117. }
  118.  
  119. /**
  120. * @brief 获取线性表中第 n 个元素
  121. *
  122. * @param pArrList 指向待获取其中的元素的线性表的指针
  123. * @param n 要获取的第 n 个元素
  124. * @param pt 用于存放获取到的元素的值的 Point2D 类型指针
  125. *
  126. * @return 获取成功返回 TRUE, 否则返回 FALSE
  127. *
  128. * @note 元素n, n 从 0 起
  129. */
  130. int GetArrListElement( ArrList *pArrList, int n, Point2D *pt )
  131. {
  132. if( n < || n > pArrList->length- )
  133. return FALSE;
  134.  
  135. pt->x = pArrList->pt[n].x;
  136. pt->y = pArrList->pt[n].y;
  137.  
  138. return TRUE;
  139. }
  140.  
  141. /**
  142. * @brief 从 nPos 处查找元素 pt 第一次出现的位置
  143. *
  144. * @param pArrList 指向待查找其中的元素的线性表的指针
  145. * @param nPos 查找起始位置
  146. * @param pt 指向待查找元素的指针
  147. *
  148. * @return 若找到, 返回元素 pt 在线性表中的位置(下标), 否则返回 -1
  149. *
  150. * @note 位置从 0 计起
  151. */
  152. int FindElement( ArrList *pArrList, int nPos, Point2D *pt )
  153. {
  154. int n = nPos;
  155. for( n; n < pArrList->length; ++n )
  156. {
  157. if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
  158. return n;
  159. }
  160.  
  161. return -;
  162. }
  163.  
  164. /**
  165. * @brief 获取线性表中 pt 元素的前驱节点到 prior_pt
  166. *
  167. * @param pArrList 指向待获取其中的元素的线性表的指针
  168. * @param pt 指向目标节点的指针
  169. * @param prior_pt 存放查找到的目标节点的前驱节点
  170. *
  171. * @return 若获取到前驱节点, 返回目标节点的前驱节点在线性表中的位置(下标), 否则返回 -1
  172. *
  173. * @note 位置从 0 计起
  174. */
  175. int GetPriorElement( ArrList *pArrList, Point2D *pt, Point2D *prior_pt )
  176. {
  177. int n = ;
  178. for( n = ; n < pArrList->length; ++n )
  179. {
  180. if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
  181. {
  182. if( n <= ) ///目标节点是头节点, 无前驱节点
  183. return -;
  184. else ///存在并找到前驱节点
  185. {
  186. prior_pt->x = pArrList->pt[n-].x;
  187. prior_pt->y = pArrList->pt[n-].y;
  188.  
  189. return n-;
  190. }
  191. }
  192. }
  193.  
  194. return -;
  195. }
  196.  
  197. /**
  198. * @brief 获取线性表中 pt 元素的后继节点到 next_pt
  199. *
  200. * @param pArrList 指向待获取其中的元素的线性表的指针
  201. * @param pt 指向目标节点的指针
  202. * @param next_pt 存放查找到的目标节点的后继节点
  203. *
  204. * @return 若获取到后继节点, 返回目标节点的后继节点在线性表中的位置(下标), 否则返回 -1
  205. *
  206. * @note 位置从 0 计起
  207. */
  208. int GetNextElement( ArrList *pArrList, Point2D *pt, Point2D *next_pt )
  209. {
  210. int n = ;
  211. for( n = ; n < pArrList->length; ++n )
  212. {
  213. if( (pArrList->pt[n].x == pt->x) && (pArrList->pt[n].y == pt->y) )
  214. {
  215. if( n >= pArrList->length- ) ///目标节点是尾节点, 无后继节点
  216. return -;
  217. else ///存在并找到后继节点
  218. {
  219. next_pt->x = pArrList->pt[n+].x;
  220. next_pt->y = pArrList->pt[n+].y;
  221.  
  222. return n+;
  223. }
  224. }
  225. }
  226.  
  227. return -;
  228. }
  229.  
  230. /**
  231. * @brief 添加一个元素至线性表末尾
  232. *
  233. * @param pArrList 指向待添加元素的线性表的指针
  234. * @param pt 指向待添加的元素的指针
  235. *
  236. * @return 成功添加则返回当前线性表长度, 否则返回 -1
  237. */
  238. int AppendToArrList( ArrList *pArrList, Point2D *pt )
  239. {
  240. if( pArrList->size - pArrList->length < ) ///检测是否需要扩容
  241. {
  242. Point2D *p = (Point2D *)calloc(pArrList->length * , sizeof(Point2D));
  243. memcpy( p, pArrList->pt, pArrList->length*sizeof(Point2D) );
  244. pArrList->size = pArrList->length * ;
  245. free( pArrList->pt );
  246. pArrList->pt = p;
  247. }
  248.  
  249. pArrList->pt[pArrList->length].x = pt->x;
  250. pArrList->pt[pArrList->length].y = pt->y;
  251.  
  252. return ++pArrList->length;
  253. }
  254.  
  255. /**
  256. * @brief 插入一个元素 pt 到线性表 nPos 处
  257. *
  258. * @param pArrList 指向待插入元素的线性表指针
  259. * @param nPos 插入的位置(下标)
  260. * @param pt 指向待插入的元素的指针
  261. *
  262. * @return 插入成功则返回当前线性表长度, 否则返回 -1
  263. *
  264. * @note 插入位置 nPos 从 0 计起
  265. */
  266. int InsertToArrList( ArrList *pArrList, int nPos, Point2D *pt )
  267. {
  268. if( (nPos < ) || (nPos > pArrList->length-) )
  269. return -;
  270.  
  271. if( pArrList->size - pArrList->length < ) ///检测是否需要扩容
  272. {
  273. Point2D *p = (Point2D *)calloc(pArrList->length*, sizeof(Point2D));
  274. memcpy( p, pArrList->pt, pArrList->length * sizeof(Point2D) );
  275. pArrList->size = pArrList->length * ;
  276. free( pArrList->pt );
  277. pArrList->pt = p;
  278. }
  279.  
  280. int nMax = pArrList->length; ///获取线性表插入1元素后的长度
  281. for( nMax; nMax > nPos; --nMax )
  282. {
  283. pArrList->pt[nMax].x = pArrList->pt[nMax-].x;
  284. pArrList->pt[nMax].y = pArrList->pt[nMax-].y;
  285. }
  286. pArrList->pt[nPos].x = pt->x;
  287. pArrList->pt[nPos].y = pt->y;
  288.  
  289. return ++pArrList->length;
  290. }
  291.  
  292. /**
  293. * @brief 从线性表上删除一个元素
  294. *
  295. * @param pArrList 指向待处理线性表的指针
  296. * @param nPos 需要删除的元素位置(下标)
  297. *
  298. * @return 成功删除返回删除后线性表长度, 否则返回 -1
  299. *
  300. * @note 删除位置 nPos 从 0 计起
  301. */
  302. int DeleteFromArrList( ArrList *pArrList, int nPos )
  303. {
  304. if( (nPos < ) || (nPos > pArrList->length - ) )
  305. return -;
  306.  
  307. if( nPos == pArrList->length - )
  308. return --pArrList->length;
  309.  
  310. for( nPos; nPos < pArrList->length; ++nPos )
  311. {
  312. pArrList->pt[nPos].x = pArrList->pt[nPos+].x;
  313. pArrList->pt[nPos].y = pArrList->pt[nPos+].y;
  314. }
  315.  
  316. return --pArrList->length;
  317. }
  318.  
  319. /**
  320. * @brief 对线性表中的元素依次执行传入的函数
  321. *
  322. * @param pArrList 指向待处理的线性表的指针
  323. * @param func 传入的函数指针
  324. *
  325. * @return void
  326. *
  327. * @note 传入的函数的参数为线性表元素类型的指针
  328. */
  329. void ForEachArrList( ArrList *pArrList, void (*func)(Point2D *pt) )
  330. {
  331. int i = ;
  332. for( i = ; i < pArrList->length; ++i )
  333. {
  334. func( &pArrList->pt[i] );
  335. }
  336. }
  337.  
  338. /**
  339. * @brief 将线性表 pArrListSrc 复制到目标线性表 pArrListDest
  340. *
  341. * @param pArrListDest 目标线性表
  342. * @param pArrListSrc 源线性表
  343. *
  344. * @return 成功则返回复制后的目标线性表的长度, 否则返回 -1
  345. */
  346. int ArrListCpy( ArrList *pArrListDest, ArrList *pArrListSrc )
  347. {
  348. if( pArrListDest->size - pArrListSrc->length < ) ///目标线性表是否需要扩容
  349. {
  350. free(pArrListDest->pt);
  351. Point2D *p = (Point2D *)calloc(pArrListSrc->length, sizeof(Point2D));
  352. pArrListDest->pt = p;
  353. pArrListDest->size = pArrListSrc->length;
  354. }
  355.  
  356. memcpy( pArrListDest->pt, pArrListSrc->pt, pArrListSrc->length * sizeof(Point2D) );
  357. pArrListDest->length = pArrListSrc->length;
  358.  
  359. return pArrListDest->length;
  360. }
  361.  
  362. /**
  363. * @brief 将线性表 pArrListSrc 连接到目标线性表 pArrListDest
  364. *
  365. * @param pArrListDest 目标线性表
  366. * @param pArrListSrc 源线性表
  367. *
  368. * @return 成功则返回连接后的目标线性表的长度, 否则返回 -1
  369. */
  370. int ArrListCat( ArrList *pArrListDest, ArrList *pArrListSrc )
  371. {
  372. if( pArrListDest->size - pArrListDest->length < pArrListSrc->length ) ///目标线性表是否需要扩容
  373. {
  374. Point2D *p = (Point2D *)calloc(pArrListDest->length + pArrListSrc->length, sizeof(Point2D));
  375. memcpy( p, pArrListDest->pt, pArrListDest->length * sizeof(Point2D) );
  376. free(pArrListDest->pt);
  377. pArrListDest->pt = p;
  378. pArrListDest->size = pArrListDest->length + pArrListSrc->length;
  379. }
  380.  
  381. int pos = ;
  382. for(pos; pos < pArrListSrc->length; ++pos )
  383. {
  384. pArrListDest->pt[pArrListDest->length + pos].x = pArrListSrc->pt[pos].x;
  385. pArrListDest->pt[pArrListDest->length + pos].y = pArrListSrc->pt[pos].y;
  386. }
  387.  
  388. pArrListDest->length += pArrListSrc->length;
  389.  
  390. return pArrListDest->length;
  391. }
  392.  
  393. //测试线性表 ArrList
  394.  
  395. //回调函数
  396. void display( Point2D *pt )
  397. {
  398. printf( "(%d,%d) ", pt->x, pt->y );
  399. }
  400.  
  401. int main()
  402. {
  403. Point2D pt1, pt2;
  404. ArrList *plstA = CreateArrList( ); //创建一个长度为 10 的线性表 plstA
  405.  
  406. ///
  407. printf("测试添加元素..\n");
  408. int i = ;
  409. for( i; i < ; ++i )
  410. {
  411. pt1.x = i; pt1.y = i;
  412. AppendToArrList( plstA, &pt1 ); //测试添加
  413. }
  414. ForEachArrList( plstA, display ); //对每个元素执行 display
  415. printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  416.  
  417. ///
  418. printf("\n测试被动扩容添加..\n");
  419. for( i = ; i < ; ++i )
  420. {
  421. pt1.x = i; pt1.y = i;
  422. AppendToArrList( plstA, &pt1 ); //测试被动扩容
  423. }
  424. ForEachArrList( plstA, display );
  425. printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  426.  
  427. ///
  428. printf("\n测试插入到头部、尾部..\n");
  429. pt1.x = ; pt1.y = ;
  430. InsertToArrList( plstA, , &pt1 ); //测试插入到首部
  431. InsertToArrList( plstA, GetArrListLength(plstA)-, &pt1 ); //测试插入到尾部
  432. ForEachArrList( plstA, display );
  433. printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  434.  
  435. ///
  436. printf("\n测试获取节点元素..\n");
  437. GetArrListElement( plstA, , &pt2 ); //获取节点位置为5的元素
  438. printf("节点坐标为5的元素pt2: (%d,%d)\n", pt2.x, pt2.y);
  439.  
  440. ///
  441. printf("\n测试获取某元素的前驱节点..\n");
  442. Point2D pri_pt, next_pt;
  443. GetPriorElement( plstA, &pt2, &pri_pt ); //获取 pt2 的前驱节点
  444. printf("pt2的前驱节点: (%d, %d)\n", pri_pt.x, pri_pt.y);
  445. GetNextElement( plstA, &pt2, &next_pt ); //获取 pt2 的后继节点
  446. printf("pt2的后继节点: (%d, %d)\n", next_pt.x, next_pt.y);
  447.  
  448. ///
  449. printf("\n测试查找元素..\n");
  450. printf("元素 next_pt 在线性表中第一次出现的位置: %d\n", FindElement(plstA, , &next_pt)); //从 0 起查找元素 next_pt
  451.  
  452. ///
  453. printf("\n测试删除某元素..\n");
  454. printf("删除位置为0的元素: ");
  455. DeleteFromArrList( plstA, ); //删除节点位置为0的元素
  456. ForEachArrList( plstA, display );
  457. printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  458.  
  459. ///
  460. printf("\n测试复制线性表..\n");
  461. printf("创建线性表 plstB : ");
  462. ArrList *plstB = CreateArrList( );
  463. for( i = ; i < ; ++i )
  464. {
  465. pt2.x = i; pt2.y = i;
  466. AppendToArrList( plstB, &pt2 );
  467. }
  468. ForEachArrList( plstB, display );
  469. printf( "\nplstB len = %d, size = %d\n", GetArrListLength(plstB), GetArrListSize(plstB) );
  470. printf("将 plstB 复制到 plstA: \n");
  471. ArrListCpy( plstA, plstB ); //将线性表 plstB 复制到 plstA
  472. ForEachArrList( plstA, display );
  473. printf( "plstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  474.  
  475. ///
  476. printf("\n测试连接线性表..\n");
  477. printf("将 plstB 连接到 plstA: ");
  478. ArrListCat( plstA, plstB ); //将线性表 plstB 连接到 plstA
  479. ForEachArrList( plstA, display );
  480. printf( "\nplstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  481.  
  482. ///
  483. printf("\n测试清空线性表..\n");
  484. ClearArrList( plstA ); //清空线性表 plstA
  485. ForEachArrList( plstA, display );
  486. printf( "plstA len = %d, size = %d\n", GetArrListLength(plstA), GetArrListSize(plstA) );
  487. printf( "IsEmpty = %d\n", IsEmptyArrList(plstA) );
  488.  
  489. ///
  490. printf("\n销毁线性表..\n");
  491. DestroyArrList( plstA ); //销毁线性表, 释放资源
  492. DestroyArrList( plstB );
  493.  
  494. return ;
  495. }

若存在 bug 或程序缺陷, 请留言反馈, 谢谢。

                                                                                                                                                                         

C语言 线性表 顺序表结构 实现的更多相关文章

  1. 数据结构C语言版--动态顺序表的基本功能实现(二)

    /* * 若各个方法结构体变量参数为: &L(即地址符加变量)则结构体变量访问结构成员变量时使用"." * 若为:*L(即取地址符加变量)则结构体变量访问结构体成员变量使用 ...

  2. 【数据结构】线性表&&顺序表详解和代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 预备知识 1.0 什么是线性表? 线性表(List)是零个或者多个数据元素的有限序列. 首先它是一个序列.里面的元素是有顺 ...

  3. C语言实现的顺序表

    顺序表是用一段地址连续的存储单元依次存储数据元素的线性结构.顺序表可分为静态存储和动态存储,静态顺序表比较简单,数据空间固定,而动态顺序表可以动态增容,便于存放大量数据,现主要把动态的基本实现一下~此 ...

  4. 线性表——顺序表的实现与讲解(C++描述)

    线性表 引言 新生安排体检,为了 便管理与统一数据,学校特地规定了排队的方式,即按照学号排队,谁在前谁在后,这都是规定好的,所以谁在谁不在,都是非常方便统计的,同学们就像被一条线(学号)联系起来了,这 ...

  5. JAVA实现具有迭代器的线性表(顺序表)

    1,先了解下JAVA类库中的迭代器:JAVA提供了两种基本类型的迭代器,分别用两个接口来表示:Iterator<T>,ListIterator<T>.其中,Iterator&l ...

  6. C语言项目实现顺序表

    #include <stdio.h> #include <stdlib.h> #include "test_顺序表声明.h" /* run this pro ...

  7. C语言学习笔记-顺序表

    #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include "coni ...

  8. C语言版本:顺序表的实现

    seqlist.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include<cstdio> #include<malloc.h> ...

  9. c语言描述的顺序表实现

    //顺序表的实现:(分配一段连续地址给顺序表,像数组一样去操作) #include<stdio.h> #include<stdlib.h> #define OK 1 #defi ...

随机推荐

  1. CentOS6 搭建Git仓库

    近期上了Redmine以后,系统集成了Git的联动功能,于是萌生了搭建内网仓库的想法,特此记录一下: 1.安装Git yum -y install git 2.创建用户及密码 useradd git ...

  2. spark Mllib基本功系列编程入门之 SVM实现分类

    话不多说.直接上代码咯.欢迎交流. /** * Created by whuscalaman on 1/7/16. */import org.apache.spark.{SparkConf, Spar ...

  3. {CSDN}{英雄会}{反相互}

    思路: 给定一个字符串,求两个不重叠的字串,他们翻转互补.其中一个字符串可以是删掉最多两个字符的原字符串子串. 动态规划,由于可以对子串进行删除操作,我首先想到了LCS问题,但需要枚举所有的长度,这样 ...

  4. Style file: generic.xaml

    All silverlight control style should be designed in generic.xaml which is in theme folder. But when ...

  5. vnc

    Xvnc, Xvnc-core, vncagent, vncinitconfig, vnclicense, vnclicensehelper, vnclicensewiz, vncpasswd, vn ...

  6. Bias and Variance

    以下内容参考 cousera 吴恩达 机器学习课程 1. Bias 和 Variance 的定义 Bias and Variance 对于改进算法具有很大的帮助作用,在bias和Variance的指引 ...

  7. 【POJ2949】Word Rings(最大平均值环)

    题意:给定N个字符串,如果A串的最后两个字母跟B串的前两个字母相同它们就能连接. 求一个由字符串组成的首尾相连的环,使(字符串总长度/字符串个数)最大. n<=100000 len<=10 ...

  8. Python随机森林算法的使用

    #coding:utf-8 # from python.Lib.packages.sklearn.tree import DecisionTreeClassifier # from python.Li ...

  9. Springmvc4 com/fasterxml/jackson/core/JsonProcessingException

    非常感谢: 谭卓博客 springmvc4 json springmvc4 集成hibernate4 出现 NoClassDefFoundError:com/fasterxml/jackson/cor ...

  10. WINDOWS的NTP配置

    将下面内容复制到记事本,保存成ntp.bat net stop w32Time REG ADD HKLM\SYSTEM\CurrentControlSet\Services\W32Time\TimeP ...