Chinaunix首页 | 论坛 | 博客
  • 博客访问: 556144
  • 博文数量: 127
  • 博客积分: 1169
  • 博客等级: 少尉
  • 技术积分: 1298
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-16 14:29
个人简介

空白

文章分类

全部博文(127)

分类: C/C++

2012-03-06 19:16:34

单链表常用操作实现:linklist.h文件
  1. /*
  2.     linklist.h
  3.     时间:2012年3月6日 14:07:17
  4.     目的:练习C语言基础知识,实现单链表常用操作
  5. */

  6. #include <stdio.h>
  7. #include <stdlib.h>

  8. #define TRUE 1
  9. #define FALSE 0
  10. #define OK 1
  11. #define ERROR 0
  12. #define INFEASIBLE -1
  13. #define OVERFLOW -2

  14. typedef int Status;
  15. typedef int ElemType;

  16. /*链表结点*/
  17. typedef struct LNode
  18. {
  19.     ElemType data;        
  20.     struct LNode * next;
  21. } * LinkList, LNode;

  22. /*构造一个空的线性表L*/
  23. Status InitLinkList(LinkList *L);

  24. /*线性表L已存在,操作结果:销毁线性表L*/
  25. void DestroyList(LinkList L);

  26. /*置空线性表,释放出头节点之外的所有的节点*/
  27. void ClearList(LinkList L);

  28. /*判断链表是否为空*/
  29. Status ListEmpty(LinkList L);

  30. /*链表L已存在,返回L中数据元素个数*/
  31. int ListLength(LinkList L);

  32. /*获取链表L中第i个结点的值*/
  33. Status GetElem(LinkList L, int i, ElemType *e);

  34. /*创建包含n个结点的链表*/
  35. void CreateList(LinkList L, int n);

  36. /*在链表L中的第i个结点之前插入一个结点*/
  37. Status ListInsert(LinkList L, int i, ElemType e);

  38. /*删除链表L中第i个位置的节点,e保存节点data域的值*/
  39. Status ListDelete(LinkList L, int i, ElemType *e);

  40. Status compile(ElemType e1, ElemType e2);

  41. int LocateElem(LinkList L, ElemType e);

  42. /*
  43. 链表L,cur_e不是第一个结点,如果链表中存在cur_e结点,则用pur_e返回该结点前驱
  44. 并返回OK,否则返回INFEASIBLE
  45. */
  46. Status PriorElem(LinkList L, ElemType cur_e, ElemType *pur_e);

  47. Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e);

  48. Status ListTransver(LinkList L);
linklist.c文件:
  1. #include "linklist.h"

  2. /*构造一个空的线性表L*/
  3. Status InitLinkList(LinkList *L)
  4. {
  5.     //生成头结点
  6.     *L = (LinkList)malloc(sizeof(LNode));
  7.     if (!(*L))
  8.     {
  9.         return ERROR;
  10.     }

  11.     (*L)->next = NULL;

  12.     return OK;
  13. }

  14. /*创建包含n个结点的链表,从表头插入数据*/
  15. void CreateList(LinkList L, int n)
  16. {
  17.     int i;
  18.     LinkList p;

  19.     for (i = n; i > 0; --i)
  20.     {
  21.         p = (LinkList)malloc(sizeof(LNode));
  22.         p->data = i;
  23.         p->next = L->next;
  24.         L->next = p;
  25.     }
  26. }

  27. /*创建包含n个结点的链表,在表尾插入数据*/
  28. void CreateList2(LinkList L, int n)
  29. {
  30.     //链表为空,L为头结点指针
  31.     int i;
  32.     LinkList p = L, s;
  33.     for (i = 1; i <= n; i++)
  34.     {
  35.         s = (LinkList)malloc(sizeof(LNode));
  36.         s->data = i;
  37.         p->next = s;
  38.         p = s;                     
  39.     }
  40.     p->next = NULL; //最后将最后插入元素的next域指向NULL
  41. }


  42. /*线性表L已存在,操作结果:销毁线性表L*/
  43. void DestroyList(LinkList L)
  44. {
  45.     LinkList q;
  46.     while (L)
  47.     {
  48.         q = L->next;
  49.         free(L);
  50.         L = q;
  51.     }
  52. }

  53. /*置空线性表,释放出头节点之外的所有的节点*/
  54. void ClearList(LinkList L)
  55. {
  56.     LinkList q = L->next, p;
  57.     while (q)
  58.     {
  59.         p = q->next; // p = q;
  60.         free(q); // q = q->next;
  61.         q = p; // free(p);
  62.     }
  63.     L->next = NULL;
  64. }

  65. /*判断链表是否为空*/
  66. Status ListEmpty(LinkList L)
  67. {
  68.     if (L->next)
  69.         return FALSE;
  70.     else
  71.         return TRUE;
  72. }

  73. /*链表L已存在,返回L中数据元素个数*/
  74. int ListLength(LinkList L)
  75. {
  76.     LinkList q = L->next; //q指向第一个结点
  77.     int i = 0;
  78.     while (q)
  79.     {    
  80.         i++;
  81.         q = q->next;
  82.     }
  83.     return i;
  84. }

  85. /*获取链表L中第i个结点的值*/
  86. Status GetElem(LinkList L, int i, ElemType *e)
  87. {
  88.     int j = 1;
  89.     LinkList q = L->next;
  90.     while (q && j < i)
  91.     {
  92.         q = q->next; //q指向i个结点
  93.         j++;
  94.     }
  95.     if (!q || j > i)
  96.     {
  97.         return ERROR;
  98.     }
  99.     *e = q->data;

  100.     return OK;
  101. }

  102. /*在链表L中的第i个结点之前插入一个结点*/
  103. Status ListInsert(LinkList L, int i, ElemType e)
  104. {
  105.     LinkList p = L, s;
  106.     int j = 1;
  107.     while (p && j < i)
  108.     {
  109.         p = p->next; //p指向第i个位置前一个结点
  110.         j++;
  111.     }
  112.     if (!p || j > i)
  113.         return ERROR;

  114.     s = (LinkList)malloc(sizeof(LNode));
  115.     s->data = e;        //
  116.     s->next = p->next; //
  117.     p->next=s;

  118.     return OK;
  119. }

  120. /*删除链表L中第i个位置的节点,并返回节点data域的值*/
  121. Status ListDelete(LinkList L, int i, ElemType *e)
  122. {
  123.     LinkList p = L, q;
  124.     int j = 1;
  125.     while (p && j < i)
  126.     {
  127.         p = p->next; //p指向第i个元素的前一个元素
  128.         j++;
  129.     }
  130.     if (!p || j > i)
  131.         return ERROR;

  132.     q = p->next; //q指向第i个元素
  133.     p->next = q->next;
  134.     *e = q->data;
  135.     free(q);
  136.     
  137.     return OK;
  138. }

  139. Status compile(ElemType e1, ElemType e2)
  140. {
  141.     if (e1 > e2)
  142.         return OK;
  143.     else
  144.         return FALSE;
  145. }

  146. int LocateElem(LinkList L, ElemType e)
  147. {
  148.     int i = 0;
  149.     LinkList p = L->next;
  150.     while (p)
  151.     {
  152.         i++;
  153.         if (compile(p->data, e))
  154.             return i;
  155.         p = p->next;
  156.     }
  157.     return 0;
  158. }


  159. /*
  160. 链表L,cur_e不是第一个结点,如果链表中存在cur_e结点,则用pur_e返回该结点前驱
  161. 并返回OK,否则返回INFEASIBLE
  162. */
  163. Status PriorElem(LinkList L, ElemType cur_e, ElemType *pur_e)
  164. {
  165.     LinkList p = L->next, q; //p指向第一个结点
  166.     while(p->next) //p的下一个结点不为空
  167.     {
  168.         q = p->next; //q指向p的下一个结点,
  169.         if (q->data == cur_e) //如果p的下一个结点值与cur_e相等
  170.         {
  171.             //*pur_e = (ElemType *)malloc(sizeof(ElemType));
  172.             *pur_e = p->data; //pur_e存放p的值
  173.             return OK;
  174.         }
  175.         p = q; //
  176.     }
  177.     return INFEASIBLE;
  178. }

  179. Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e)
  180. {
  181.     LinkList p = L->next;
  182.     while (p->next)
  183.     {
  184.         if (p->data == cur_e)
  185.         {
  186.             *next_e = p->next->data;
  187.             return OK;
  188.         }
  189.         p = p->next;
  190.     }
  191.     return INFEASIBLE;
  192. }

  193. /*对链表结点数据域排序,由大到小输出*/
  194. void ListSort(LinkList L)
  195. {
  196.     int i, j, tmp, len = ListLength(L);
  197.     LinkList p, q;
  198.     for (i = 0, p = L->next; i < len - 1; i++, p = p->next)
  199.     {
  200.         for (j = 0, q = L->next; j < len - i - 1; j++, q = q->next)
  201.         {
  202.             if (q->data > q->next->data)
  203.             {
  204.                 tmp = q->data;
  205.                 q->data = q->next->data;
  206.                 q->next->data = tmp;
  207.             }
  208.         }
  209.     }
  210. }

  211. Status ListTransver(LinkList L)
  212. {
  213.     LinkList p = L->next; //p指向第一个有效结点
  214.     while (NULL != p)
  215.     {
  216.         printf("%d ", p->data);
  217.         p = p->next;
  218.     }
  219.     printf("\n");
  220.     return OK;
  221. }

测试主函数:main.c
  1. #include "linklist.c"

  2. int main()
  3. {
  4.     //LinkList L = (LinkList)malloc(sizeof(LNode));
  5.     LinkList L;
  6.     ElemType e;
  7.     printf("初始化链表:-->");
  8.     if(InitLinkList(&L))
  9.     {
  10.         printf("链表初始化成功!\n");
  11.     }

  12.     /*----------------------------*/
  13.     printf("创建链表:\n");
  14.     int n;
  15.     printf("-->输入链表结点数量: ");
  16.     scanf("%d", &n);
  17.     CreateList(L, n);
  18.     printf("-->创建%d个结点链表为: ", n);
  19.     ListTransver(L);
  20.     printf("-->链表长度为: %d\n", ListLength(L));

  21.     /*----------------------------*/
  22.     printf("链表是否为空: ");
  23.     if (FALSE == ListEmpty(L))
  24.         printf("非空\n");
  25.     else
  26.         printf("空\n");

  27.     //-----------------------------
  28.     printf("释放链表中除头结点之外的所有结点: \n");
  29.     ClearList(L);
  30.     printf("-->链表是否为空: ");
  31.     if (FALSE == ListEmpty(L))
  32.         printf("非空\n");
  33.     else
  34.         printf("空\n");
  35.     printf("-->链表长度为: %d\n", ListLength(L));

  36.     //----------------------------------------
  37.     printf("创建新链表:\n");
  38.     printf("-->输入链表结点数量: ");
  39.     scanf("%d", &n);
  40.     CreateList2(L, n);
  41.     printf("-->创建%d个结点链表为: ", n);
  42.     ListTransver(L);
  43.     printf("-->链表长度: %d\n", ListLength(L));

  44.     //在第3个结点之前插入结点
  45.     printf("在第3个结点之前插入结点: \n");
  46.     ListInsert(L, 3, 6);
  47.     printf("-->插入新结点后: ");
  48.     ListTransver(L);

  49.     //将链表数据域按从大到小排序
  50.     printf("-->链表数据域按从大到小排序: \n");
  51.     printf("排序前: ");
  52.     ListTransver(L);
  53.     ListSort(L);
  54.     printf("排序后: ");
  55.     ListTransver(L);
  56.     
  57.     //获取第3个结点值
  58.     printf("获取第4个结点值: \n");
  59.     GetElem(L, 4, &e);
  60.     printf("-->第3个结点的值为: %d\n", e);

  61.     //删除第4个结点的值
  62.     printf("删除第3个结点的值:\n");
  63.     printf("删除前链表: ");
  64.     ListTransver(L);
  65.     ListDelete(L, 3, &e);
  66.     printf("-->第3个结点的值为: %d\n", e);
  67.     printf("删除后链表: ");
  68.     ListTransver(L);

  69.     //获取指定结点前驱
  70.     
  71.     //e = (ElemType *)malloc(sizeof(ElemType));
  72.     printf("获取值为5的结点的前驱: \n");
  73.     if (PriorElem(L, 5, &e) == OK)
  74.     {
  75.         printf("-->该结点有前驱,前驱值为: %d\n", e);
  76.     }
  77.     else
  78.     {
  79.         printf("-->不存在值为5的结点的前驱\n");
  80.     }

  81.     //获取指定结点后驱
  82.     printf("获取值为5的结点的后驱: \n");
  83.     if (NextElem(L, 5, &e) == OK)
  84.     {
  85.         printf("-->该结点有后驱,前驱值为: %d\n", e);
  86.     }
  87.     else
  88.     {
  89.         printf("-->不存在值为5的结点的后驱\n");
  90.     }
  91.     //free(e);

  92.     //释放整个链表
  93.     DestroyList(L);
  94.     //ListTransver(L);
  95.     return OK;
  96. }

阅读(2017) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~