当前位置:   article > 正文

数据结构(C语言)之——顺序表_printelem

printelem
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. //定义元素类型
  5. typedef struct {
  6. char* name; //元素名
  7. int value; //元素值
  8. }Elem;
  9. Elem* createElem(char* name, int value); //指定元素名和元素值创建一个新元素
  10. bool alterElem(Elem* e, char* newName, int newValue); //修改元素的值为新的值
  11. bool copyElem(Elem* eCopy, Elem* e); //将元素e的值复制给eCopy。(eCopy仅为一个指针)
  12. bool isSameElem(Elem* e1, Elem* e2); //判断两个元素的所有属性是否相同(元素名和元素值都相同)
  13. void printElem(Elem* e); //打印元素信息
  14. //线性表结构
  15. typedef struct {
  16. Elem** data; //用数组存储线性表中的元素
  17. int length; //顺序表的当前长度
  18. int maxSize; //顺序表的最大长度
  19. }SeqList;
  20. /****************************************创建、初始化和释放*****************************************/
  21. SeqList* createList(int maxSize); //创建一个最大长度为maxSize的空表并初始化
  22. void releaseList(SeqList* list); //释放线性表开辟的内存空间
  23. /*************************************************增*************************************************/
  24. bool headInsertList(SeqList* list, Elem* e); //头插。在表头位置插入元素e。插入成功返回true,失败返回false
  25. bool tailInsertList(SeqList* list, Elem* e); //尾插。在表尾插入元素e。插入成功返回true,失败返回false
  26. bool insertList(SeqList* list, int pos, Elem* e); //指定位置插入元素。在顺序表的第pos(1≤pos≤n)个位置插入元素e,成功返回true,失败返回false。
  27. /*************************************************删*************************************************/
  28. bool headDeleteList(SeqList* list); //头删,删除表中的第1个元素。删除成功返回true,失败返回false
  29. bool tailDeleteList(SeqList* list); //尾删,删除表尾元素。删除成功返回true,失败返回false
  30. bool deleteList(SeqList* list, int index); //指定位置删除元素。删除顺序表list的第pos(1≤pos≤n)个数据元素。删除成功返回true,删除失败返回false。
  31. bool clearList(SeqList* list); //清空顺序表。清空成功返回true,清空失败返回false。
  32. /*************************************************改*************************************************/
  33. bool alterList(SeqList* list, int pos, char* newName, int newValue); //修改表中第pos(1≤pos≤n)个元素的值。修改成功返回true,修改失败返回false。
  34. /*************************************************查*************************************************/
  35. int locateElem(SeqList* list, char* name, int value); //根据元素名和元素值来查找数据元素e在表中的位置,如果有,返回位置pos(1≤pos≤n);如果没有,返回-1
  36. Elem* getElem(SeqList* list, int pos); //返回顺序表中第pos(1≤pos≤n)个元素的Elem指针。查找失败返回NULL。
  37. bool isNotLegalPosition(SeqList* list, int pos); //判断插入位置pos(1≤pos≤n)是否非法。非法则返回true,合法则返回false。
  38. bool isEmpty(SeqList* list); //判断顺序表是否为空
  39. bool isFull(SeqList* list); //判断顺序表是否已满
  40. int listLength(SeqList* list); //求顺序表的长度
  41. void printList(SeqList* list); //打印顺序表
  42. /*************************************************其它*************************************************/
  43. SeqList* mergeList(SeqList* list1, SeqList* list2); //合并顺序表。将list2加入到list1后面,返回合并后的新表。合并失败返回NULL
  44. SeqList* reverseList(SeqList* list); //反转顺序表元素,返回一个倒序的新表。反转失败返回NULL。
  45. SeqList* reversePartList(SeqList* list, int startPos, int endPos); //反转部分顺序表元素。反转从第startPos到第endPos的元素,包括startPos和endPos位置的元素。反转失败返回NULL。
  46. int sameElemCount(SeqList* list1, SeqList* list2); //返回两个顺序表中相同元素个数
  47. bool alterListFromOther(SeqList* list, int pos, SeqList* otherList, int otherPos); //将表list的第pos个元素设置设置为与表otherList的第otherPos个元素相同
  48. void main() {
  49. SeqList* list = createList(100);
  50. printf("/*************************************************增*************************************************/\n");
  51. //头插法插入元素
  52. headInsertList(list, createElem("a", 1));
  53. printf("头插法插入元素:(a,1),操作后表为:");printList(list);
  54. //指定索引处插入元素
  55. insertList(list, 2, createElem("b", 2));
  56. printf("在第二个位置插入元素:(b,2),操作后表为:");printList(list);
  57. insertList(list, 3, createElem("c", 3));
  58. printf("在第三个位置插入元素:(c,3),操作后表为:");printList(list);
  59. //尾插法插入元素
  60. tailInsertList(list, createElem("d", 4));
  61. printf("尾插法插入元素:(d,4),操作后表为:");printList(list);
  62. printf("顺序表的长度为:%d\n",listLength(list));
  63. printf("/*************************************************查*************************************************/\n");
  64. printf("元素(c,3)在顺序表中的位置为:%d\n", locateElem(list, "c", 3));
  65. printf("顺序表中第2个元素为:"); printElem(getElem(list, 2)); printf("\n");
  66. printf("/*************************************************改*************************************************/\n");
  67. alterList(list, 4, "x", 100);
  68. printf("修改顺序表中第4个元素的值为(x, 100),操作后表为:"); printList(list);
  69. printf("/*************************************************删*************************************************/\n");
  70. //头删法删除元素
  71. headDeleteList(list);
  72. printf("头删法删除元素,操作后表为:");printList(list);
  73. //指定索引处删除元素
  74. deleteList(list, 2);
  75. printf("删除第2个元素,操作后表为:");printList(list);
  76. //尾删法删除元素
  77. tailDeleteList(list);
  78. printf("尾删法删除元素,操作后表为:");printList(list);
  79. //清空顺序表
  80. clearList(list);
  81. printf("清空顺序表,操作后表为:");printList(list);
  82. printf("顺序表的长度为:%d\n",listLength(list));
  83. releaseList(list);
  84. printf("/*************************************************其它*************************************************/\n");
  85. //合并表
  86. printf("表1:(a,1) (b,2) (c,3);");
  87. SeqList* list1 = createList(100);
  88. tailInsertList(list1, createElem("a", 1));
  89. tailInsertList(list1, createElem("b", 2));
  90. tailInsertList(list1, createElem("c", 3));
  91. printf("表2:(c,3) (d,4) (e,5); ");
  92. SeqList* list2 = createList(100);
  93. tailInsertList(list2, createElem("c", 3));
  94. tailInsertList(list2, createElem("d", 4));
  95. tailInsertList(list2, createElem("e", 5));
  96. printf("表1和表2相同元素个数为:%d", sameElemCount(list1, list2));
  97. SeqList* list12 = mergeList(list1, list2);
  98. printf("\n合并后:"); printList(list12);
  99. SeqList* list21 = reverseList(list12); printf("反转所有元素,反转后:"); printList(list21);
  100. printf("将合并表的第3个元素设置位反转表的第2个元素,设置后合并表为:"); alterListFromOther(list12, 3, list21, 2); printList(list12);
  101. printf("合并表和反转表相同元素个数为:%d\n", sameElemCount(list12, list21));
  102. SeqList* list21_part = reversePartList(list12, 2, 5);
  103. printf("反转第2到第5的元素,反转后:"); printList(list21_part); printf("\n");
  104. releaseList(list1);
  105. releaseList(list2);
  106. releaseList(list12);
  107. releaseList(list21);
  108. releaseList(list21_part);
  109. }
  110. //指定元素名和元素值创建一个新元素
  111. Elem* createElem(char* name, int value) {
  112. Elem* e = (Elem*) malloc(sizeof(Elem));
  113. if(e == NULL) { //开辟失败则直接返回
  114. printf("创建元素失败!\n");
  115. return NULL;
  116. }
  117. e->name = (char*) malloc(sizeof(char)*(strlen(name)+1));
  118. strcpy(e->name, name);
  119. e->value = value;
  120. return e;
  121. }
  122. //修改元素的值为新的值。修改成功返回true,修改失败返回false。
  123. bool alterElem(Elem* e, char* newName, int newValue) {
  124. if(e == NULL || newName == NULL) {
  125. return false;
  126. }
  127. free(e->name);
  128. e->name = (char* ) malloc(sizeof(char)*(strlen(newName)+1));
  129. strcpy(e->name, newName);
  130. e->value = newValue;
  131. return true;
  132. }
  133. //将元素e的值复制给eCopy。(eCopy仅为一个指针)
  134. bool copyElem(Elem* eCopy, Elem* e) {
  135. eCopy->name = (char*) malloc(sizeof(char)*(strlen(e->name)+1)); //注意加1,因为有'\0'
  136. if(eCopy->name == NULL) {
  137. return NULL;
  138. }
  139. strcpy(eCopy->name, e->name); //复制元素名
  140. eCopy->value = e->value; //复制元素值
  141. return true;
  142. }
  143. //判断两个元素属性是否相同(元素名和元素值都相同)
  144. bool isSameElem(Elem* e1, Elem* e2) {
  145. //如果有一个是NULL,返回false
  146. if(e1 == NULL || e2 == NULL) {
  147. return false;
  148. }
  149. return strcmp(e1->name, e2->name) == 0 ? e1->value == e2->value : false;
  150. }
  151. //打印元素信息
  152. void printElem(Elem* e) {
  153. printf("(%s, %d)", e->name, e->value);
  154. }
  155. //创建一个最大长度为maxSize的空表并初始化
  156. SeqList* createList(int maxSize) {
  157. SeqList* list = (SeqList *) malloc(sizeof(SeqList)); //开辟线性表内存空间
  158. list->data = (Elem **) malloc(sizeof(Elem*) * maxSize); //开辟元素指针数组的内存空间
  159. //给元素指针数组的每一个元素指针指向一个元素空间
  160. for(int i = 0; i < maxSize; i++) {
  161. list->data[i] = (Elem*) malloc(sizeof(Elem));
  162. }
  163. list->length = 0; //线性表长度初始化为0
  164. list->maxSize = maxSize; //设置最大长度
  165. return list;
  166. }
  167. //释放线性表开辟的内存空间
  168. void releaseList(SeqList* list) {
  169. //释放元素指针数组的各个指针所指的内存Elem
  170. for(int i = 0; i < list->length; i ++) {
  171. free(list->data[i]->name); //释放元素名指针所指空间(char* name)
  172. free(list->data[i]); //释放元素指针所指空间(*Elem list->data[i])
  173. }
  174. free(list->data); //释放元素指针数组所占的内存(Elem** data)
  175. free(list); //释放顺序表所占内存(SeqList* list)
  176. }
  177. //头插,在表头位置插入元素e。插入成功返回true,失败返回false
  178. bool headInsertList(SeqList* list, Elem* e) {
  179. //判断该表是否已满
  180. if(isFull(list)) {
  181. return false;
  182. }
  183. //将所有元素后移
  184. for(int i = list->length-1; i >= 0; i--) {
  185. list->data[i+1] = list->data[i];
  186. }
  187. list->data[0] = e; //在头部插入新的元素
  188. list->length += 1; //线性表长度加1
  189. return true;
  190. }
  191. //头删,删除表中的第一个元素。删除成功返回true,失败返回false
  192. bool headDeleteList(SeqList* list) {
  193. //判断该表是否为空
  194. if(isEmpty(list)) {
  195. return false;
  196. }
  197. //释放第0个元素指针所指内存
  198. free(list->data[0]);
  199. //将第1个至第n-1个元素依次前移一位
  200. for(int i = 1; i < list->length; i ++) {
  201. list->data[i-1] = list->data[i];
  202. }
  203. list->length -= 1; //顺序表长度减1
  204. return true;
  205. }
  206. //尾插,在表尾插入元素e。插入成功返回true,失败返回false
  207. bool tailInsertList(SeqList* list, Elem* e) {
  208. //判断该表是否已满
  209. if(isFull(list)) {
  210. return false;
  211. }
  212. list->data[list->length] = e; //在表尾插入元素
  213. list->length += 1; //顺序表长度加1
  214. return true;
  215. }
  216. //尾删,删除表尾元素。删除成功返回true,失败返回false
  217. bool tailDeleteList(SeqList* list) {
  218. //判断该表是否为空
  219. if(isEmpty(list)) {
  220. return false;
  221. }
  222. //释放最后一个元素指针所指的内存
  223. free(list->data[list->length-1]);
  224. //将顺序表长度减1
  225. list->length -= 1;
  226. return true;
  227. }
  228. //指定位置插入元素。在顺序表的第i个位置(1≤i≤n)插入元素e,成功返回true,失败返回false
  229. bool insertList(SeqList* list, int pos, Elem* e) {
  230. //判断插入位置是否非法
  231. if(isNotLegalPosition(list, pos)) {
  232. return false;
  233. }
  234. //判断该表是否已满
  235. if(isFull(list)) {
  236. return false;
  237. }
  238. //将第i个及之后的元素后移
  239. int i;
  240. for(i = list->length-1; i >= pos-1; i--) {
  241. list->data[i+1] = list->data[i];
  242. }
  243. list->data[pos-1] = e; //在第pos位放入元素e
  244. list->length += 1; //线性表的长度加1
  245. return true;
  246. }
  247. //指定位置删除元素。删除顺序表list的第pos个数据元素。删除成功返回true,删除失败返回false。
  248. bool deleteList(SeqList* list, int pos) {
  249. //判断删除位置是否非法
  250. if(isNotLegalPosition(list, pos)) {
  251. return false;
  252. }
  253. //判断该表是否为空
  254. if(isEmpty(list)) {
  255. return false;
  256. }
  257. //释放第pos个元素指针所指内存
  258. free(list->data[pos-1]);
  259. //删除该元素
  260. for(int i = pos; i < list->length; i++) {
  261. list->data[i-1] = list->data[i];
  262. }
  263. list->length -= 1;
  264. return true;
  265. }
  266. //清空顺序表。清空成功返回true,清空失败返回false。
  267. bool clearList(SeqList* list) {
  268. //判断是否已经为空
  269. if(isEmpty(list)) {
  270. return true;
  271. }
  272. //清空元素指针数组的所有指针指向的元素Elem内存
  273. for(int i = 0; i < list->length; i++) {
  274. free(list->data[i]);
  275. }
  276. list->length = 0; //顺序表长度置为0
  277. return true;
  278. }
  279. //修改表中第pos个元素的值。修改成功返回true,修改失败返回false。
  280. bool alterList(SeqList* list, int pos, char* newName, int newValue) {
  281. //判断index是否非法
  282. if(isNotLegalPosition(list, pos)) {
  283. return false;
  284. }
  285. //判断表是否为空
  286. if(isEmpty(list)) {
  287. return false;
  288. }
  289. return alterElem(list->data[pos-1], newName, newValue);
  290. }
  291. //根据元素名和元素值来查找第一个相同的数据元素e在表中的位置,如果有,返回位置pos;如果没有,返回-1
  292. int locateElem(SeqList* list, char* name, int value) {
  293. //判断表是否为空
  294. if(isEmpty(list)) {
  295. return -1;
  296. }
  297. int result = -1;
  298. //strcmp(char* a,char* b)就可以比较出两字符串是否相等
  299. for(int i = 0; i < list->length; i++) {
  300. if(strcmp(list->data[i]->name, name) == 0
  301. && list->data[i]->value == value) {
  302. result = i+1;
  303. break;
  304. }
  305. }
  306. return result;
  307. }
  308. //返回顺序表中指向第pos个元素Elem指针。索引失败返回NULL。
  309. Elem* getElem(SeqList* list, int pos) {
  310. //判断index索引是否非法
  311. if(isNotLegalPosition(list, pos)) {
  312. return NULL;
  313. }
  314. return list->data[pos-1];
  315. }
  316. //判断插入位置pos是否非法。非法则返回true,合法则返回false。
  317. bool isNotLegalPosition(SeqList* list, int pos) {
  318. if(pos-1 < 0 || pos-1 > list->length) {
  319. return true;
  320. }else {
  321. return false;
  322. }
  323. }
  324. //判断顺序表是否为空
  325. bool isEmpty(SeqList* list) {
  326. if(list->length == 0) {
  327. return true;
  328. }else {
  329. return false;
  330. }
  331. }
  332. //判断顺序表是否已满
  333. bool isFull(SeqList* list) {
  334. if(list->length >= list->maxSize) {
  335. return true;
  336. } else {
  337. return false;
  338. }
  339. }
  340. //求顺序表的长度
  341. int listLength(SeqList* list) {
  342. return list->length;
  343. }
  344. //打印顺序表
  345. void printList(SeqList* list) {
  346. for(int i = 0; i < list->length; i++) {
  347. printElem(list->data[i]);
  348. printf(" ");
  349. }
  350. printf("\n");
  351. }
  352. //合并顺序表。将list2加入到list1后面,返回合并后的表。合并失败返回NULL
  353. SeqList* mergeList(SeqList* list1, SeqList* list2) {
  354. //创建一个新表,最大长度是两表最大长度之和
  355. SeqList* newList = createList(list1->maxSize + list2->maxSize);
  356. //将list1的元素复制到新表中
  357. newList->length = list1->length + list2->length;
  358. int i;
  359. for(i = 0; i < list1->length; i++) {
  360. copyElem(newList->data[i], list1->data[i]);
  361. }
  362. //将list2的元素也复制到新表中
  363. for(i = list1->length; i < newList->length; i++) {
  364. copyElem(newList->data[i], list2->data[i - list1->length]);
  365. }
  366. return newList;
  367. }
  368. //反转顺序表元素,返回一个倒序的新表
  369. SeqList* reverseList(SeqList* list) {
  370. SeqList* newList = createList(list->maxSize);
  371. if(newList == NULL) {
  372. return NULL;
  373. }
  374. newList->length = list->length;
  375. //将list表中所有元素复制过来
  376. for(int i = 0; i < list->length; i++) {
  377. copyElem(newList->data[i], list->data[list->length - i -1]);
  378. }
  379. return newList;
  380. }
  381. //反转部分顺序表元素。反转从第startPos到第endPos的元素,包括startPos和endPos位置的元素。反转失败返回NULL。
  382. SeqList* reversePartList(SeqList* list, int startPos, int endPos) {
  383. SeqList* newList = createList(list->maxSize);
  384. if(newList == NULL) {
  385. return NULL;
  386. }
  387. if(startPos < 1 || endPos > list->length) {
  388. return NULL;
  389. }
  390. newList->length = list->length;
  391. int i;
  392. for(i = 0; i <= startPos - 2; i ++) {
  393. copyElem(newList->data[i], list->data[i]);
  394. }
  395. for(i = startPos - 1; i <= endPos - 1; i++) {
  396. copyElem(newList->data[i], list->data[(endPos -1) + (startPos - 1) - i]);
  397. }
  398. for(i = endPos; i < list->length; i++) {
  399. copyElem(newList->data[i], list->data[i]);
  400. }
  401. return newList;
  402. }
  403. //返回两个顺序表中相同元素个数
  404. int sameElemCount(SeqList* list1, SeqList* list2) {
  405. int count = 0;
  406. for(int i = 0; i < list1->length; i++) {
  407. for(int j = 0; j < list2->length; j++) {
  408. if(isSameElem(list1->data[i], list2->data[j])) {
  409. count += 1;
  410. break;
  411. }
  412. }
  413. }
  414. return count;
  415. }
  416. //将表list的第pos个元素设置设置为与表otherList的第otherPos个元素相同
  417. bool alterListFromOther(SeqList* list, int pos, SeqList* otherList, int otherPos) {
  418. if(list == NULL || otherList == NULL) {
  419. return false;
  420. }
  421. if(isNotLegalPosition(list, pos) || isNotLegalPosition(otherList, otherPos)) {
  422. return false;
  423. }
  424. alterElem(list->data[pos -1], otherList->data[otherPos - 1]->name, otherList->data[otherPos -1]->value);
  425. return true;
  426. }
  1. 结果:
  2. /*************************************************增*************************************************/
  3. 头插法插入元素:(a,1),操作后表为:(a, 1)
  4. 在第二个位置插入元素:(b,2),操作后表为:(a, 1) (b, 2)
  5. 在第三个位置插入元素:(c,3),操作后表为:(a, 1) (b, 2) (c, 3)
  6. 尾插法插入元素:(d,4),操作后表为:(a, 1) (b, 2) (c, 3) (d, 4)
  7. 顺序表的长度为:4
  8. /*************************************************查*************************************************/
  9. 元素(c,3)在顺序表中的位置为:3
  10. 顺序表中第2个元素为:(b, 2)
  11. /*************************************************改*************************************************/
  12. 修改顺序表中第4个元素的值为(x, 100),操作后表为:(a, 1) (b, 2) (c, 3) (x, 100)
  13. /*************************************************删*************************************************/
  14. 头删法删除元素,操作后表为:(b, 2) (c, 3) (x, 100)
  15. 删除第2个元素,操作后表为:(b, 2) (x, 100)
  16. 尾删法删除元素,操作后表为:(b, 2)
  17. 清空顺序表,操作后表为:
  18. 顺序表的长度为:0
  19. /*************************************************其它*************************************************/
  20. 1:(a,1) (b,2) (c,3);表2:(c,3) (d,4) (e,5); 表1和表2相同元素个数为:1
  21. 合并后:(a, 1) (b, 2) (c, 3) (c, 3) (d, 4) (e, 5)
  22. 反转所有元素,反转后:(e, 5) (d, 4) (c, 3) (c, 3) (b, 2) (a, 1)
  23. 将合并表的第3个元素设置位反转表的第2个元素,设置后合并表为:(a, 1) (b, 2) (d, 4) (c, 3) (d, 4) (e, 5)
  24. 合并表和反转表相同元素个数为:6
  25. 反转第2到第5的元素,反转后:(a, 1) (d, 4) (c, 3) (d, 4) (b, 2) (e, 5)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/593849
推荐阅读
相关标签
  

闽ICP备14008679号