鱼C论坛

 找回密码
 立即注册
查看: 2509|回复: 1

[技术交流] 线性表11的作业题

[复制链接]
发表于 2016-2-16 01:17:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
最近一直在看小甲鱼老师的数据结构,以前没有学过数据结构这一门。由于是新鱼油,下载不了课件来学,只能看着视频,跟着老师一起
敲代码。看到单链表留下了作业,觉得蛮有意思。就根据前面学到的知识都用上了,比小甲鱼老师的多增加了一些功能,方便各位新手学习,对于高手的话就直接飘过吧~~~~~

  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include "time.h"

  4. #define OK                        1
  5. #define ERROR                0
  6. // #define TRUE                1
  7. // #define FALSE                0


  8. typedef int Status;
  9. typedef int ElemType;


  10. //链表结点结构
  11. struct tagNode
  12. {
  13.         ElemType data;
  14.         struct tagNode *next;

  15. };

  16. typedef struct tagNode *LinkList,Node;



  17. ///////////////////函数声明///////////////////////
  18. //初始化空链表
  19. Status InitList(LinkList* linkHead);
  20. //求链表长度
  21. int ListLength(LinkList L);
  22. //获取中间结点元素
  23. Status GetMidNode(LinkList L,ElemType *e);
  24. //尾插法建立单链表
  25. void CreateListTail(LinkList *L, int n);
  26. //单链表整表删除
  27. Status ClearList(LinkList *L);
  28. //查看链表
  29. Status PrintList(LinkList L);
  30. //初始条件: 顺序线性表L已存在, 1<=i<=ListLength(L)
  31. //操作结果: 在L中第i个位置之前插入新的数据元素e, L长度+1
  32. Status ListInsert(LinkList *L, int i, ElemType e);
  33. //链式存储结构  删除链表某位的元素数据
  34. Status ListDelete(LinkList *L, int i, ElemType* e);
  35. //删除空链表
  36. Status OverList(LinkList *L);

  37. //////////////////////////////////////////////////


  38. //初始化空链表
  39. Status InitList(LinkList* linkHead)
  40. {
  41.         LinkList        r; //临时变量指针,用来存放结点地址,方便调用
  42.         *linkHead = (LinkList)malloc(sizeof(Node));
  43.        
  44.         r = *linkHead; //结点的地址

  45.         if(r == NULL)
  46.                 return ERROR;

  47.         r->data = 0;
  48.         r->next = NULL;


  49.         return OK;

  50. }

  51. //求链表长度
  52. int ListLength(LinkList L)
  53. {
  54.         int icount = 0;

  55.         if(L)
  56.         {
  57.                 LinkList r = L->next;
  58.                
  59.                 while(r)
  60.                 {
  61.                         r = r->next;
  62.                         icount++;
  63.                 }
  64.         }


  65.         return icount;
  66. }

  67. //获取中间结点元素
  68. Status GetMidNode(LinkList L,ElemType *e)
  69. {
  70.         LinkList search, mid;
  71.         mid = search = L;

  72.         if(NULL == L)
  73.                 return (*e=ERROR);

  74.         if(NULL == L->next)
  75.                 return (*e=ERROR);
  76.        
  77.         while( search->next != NULL )
  78.         {
  79.                 //search移动的速度是 mid 的2倍
  80.                 if( search->next->next != NULL )
  81.                 {
  82.                         search = search->next->next;
  83.                         mid = mid->next;
  84.                 }else
  85.                 {
  86.                         search = search->next;
  87.                 }
  88.         }
  89.        
  90.         *e = mid->data;
  91.        
  92.         return OK;
  93.        
  94. }


  95. //尾插法建立单链表
  96. void CreateListTail(LinkList *L, int n)
  97. {
  98.         LinkList p, r;
  99.         int i;
  100.        
  101.         srand(time(0));
  102.         *L = (LinkList)malloc(sizeof(Node)); //我们传入地址
  103.         r = *L; //r是当前的结点
  104.        
  105.         for(i = 0; i < n; i++)
  106.         {
  107.                 p = (Node*)malloc(sizeof(Node));
  108.                 p->data = rand()%100 +1;
  109.                 r->next = p;
  110.                 r = p;

  111.                 printf("%d ",p->data);
  112.         }
  113.        
  114.         printf("\n");

  115.         r->next = NULL;
  116. }

  117. //单链表整表删除
  118. /*
  119. 单链表整表删除的算法思路如下:
  120. 声明结点p和q;
  121. 将第一个结点赋值给p,下一结点赋值给q;
  122. 循环执行释放p和将q赋值给p的操作;

  123. */

  124. Status ClearList(LinkList *L)
  125. {
  126.         LinkList p, q;
  127.        
  128.         p = (*L)->next;
  129.        
  130.         while(p)
  131.         {
  132.                 q = p->next;
  133.                 free(p);
  134.                 p = q;
  135.         }
  136.        
  137.         (*L)->next = NULL;  //这样就剩下了一个头结点的空表
  138.        
  139.         return OK;
  140. }

  141. //查看链表
  142. Status PrintList(LinkList L)
  143. {       
  144.         if(L)
  145.         {
  146.                 LinkList r = L->next;
  147.                
  148.                 while(r)
  149.                 {
  150.                         printf("%d ",r->data);

  151.                         r = r->next;
  152.                 }
  153.         }else
  154.                 return ERROR;
  155.        
  156.         printf("\n");
  157.        
  158.         return OK;
  159. }

  160. //链式存储结构的线性表 如:链表
  161. //初始条件: 顺序线性表L已存在, 1<=i<=ListLength(L)
  162. //操作结果: 在L中第i个位置之前插入新的数据元素e, L长度+1

  163. Status ListInsert(LinkList *L, int i, ElemType e)
  164. {
  165.         int j;
  166.         LinkList p, s;
  167.        
  168.         p = *L;
  169.         j = 1;
  170.        
  171.         //寻找i位置
  172.         while( p && j<i)
  173.         {
  174.                 p = p->next;
  175.                 j++;
  176.         }
  177.        
  178.         //检测p是否到达链表尾NULL 或者 没找到i
  179.         if( !p || j>i)
  180.         {
  181.                 return ERROR;
  182.         }
  183.        
  184.         //创建新结点
  185.         s = (LinkList)malloc(sizeof(Node));
  186.         //给新结点数据域赋值
  187.         s->data = e;
  188.         //修正新结点指针域
  189.         s->next = p->next;
  190.         p->next = s;
  191.        
  192.        
  193.         return OK;
  194. }

  195. //链式存储结构  删除链表某位的元素数据
  196. Status ListDelete(LinkList *L, int i, ElemType* e)
  197. {
  198.         int j;
  199.         LinkList p, q;
  200.        
  201.         p = *L;
  202.         j = 1;
  203.        
  204.         //寻找第i位置的结点
  205.         //结果有3种可能:
  206.         //1: 找到了,不过p是第i-1的结点,p->next就是要删除的结点
  207.         //2: 到达NULL尾
  208.         //3: 不存在i位置元素
  209.         while( p->next && j<i )
  210.         {
  211.                 p = p->next;
  212.                 ++j;
  213.         }
  214.        
  215.         //排除2、3可能
  216.         if( !(p->next) || j>i )
  217.         {
  218.                 return ERROR;
  219.         }
  220.        
  221.         //获取要删除结点到q
  222.         q = p->next;
  223.         //断链
  224.         p->next = q->next;
  225.        
  226.         //保存删除结点数据
  227.         *e = q->data;
  228.         //回收创建结点时申请的内存
  229.         free(q);
  230.        
  231.        
  232.         return OK;
  233. }

  234. //删除空链表
  235. Status OverList(LinkList *L)
  236. {
  237.         LinkList r = NULL; //临时指针变量

  238.         r = *L;
  239.         if(r)
  240.         {
  241.                 if( NULL == r->next )
  242.                 {
  243.                         //这个就是链表头结点,我们回收它
  244.                         free(r);
  245.                         *L = r = NULL;
  246.                         return OK;
  247.                 }
  248.         }

  249.         return ERROR;
  250. }

  251. //输出界面
  252. void OutMenu()
  253. {
  254.         printf("1.查看链表\n");
  255.         printf("2.创建链表(尾插法)\n");
  256.         printf("3.链表长度\n");
  257.         printf("4.中间结点值\n");
  258.         printf("5.整表删除,空表\n");
  259.         printf("6.删除空表,结束掉创建的线性表\n");
  260.         printf("7.在第3号位置插入23\n");
  261.         printf("8.删除第5号位置元素数据\n");
  262.         printf("0.退出\n");
  263.         printf("请选择你的操作:\n");
  264. }

  265. /////////////----------------------------------------------------------------//////////////////////////
  266. int main(int argn, char* argv[], char* arge[])
  267. {
  268.         //初始化L后:ListLength(L)=0
  269.         //1.查看链表
  270.         //2.创建链表(尾插法)
  271.         //3.链表长度
  272.         //4.中间结点值
  273.         //0.退出
  274.         //请选择你的操作:

  275.         LinkList linkHead = NULL;
  276.         int nSelect = -1;
  277.         ElemType e = 0, insert_e = 23, delsert_e;

  278.         if( InitList(&linkHead) )
  279.         {
  280.                 printf("初始化L后:ListLength(L)=%d\n\n",ListLength(linkHead));
  281.         }
  282.        
  283.         //输出界面
  284.         OutMenu();

  285.         //循环选择
  286.         while(1)
  287.         {
  288.                 scanf("%d",&nSelect);

  289.                 switch(nSelect)
  290.                 {
  291.                 case 1:
  292.                 //        printf("查看链表\n");
  293.                         PrintList(linkHead);
  294.                         break;
  295.                 case 2:
  296.                         printf("整体创建L元素(尾插法):\n");
  297.                         CreateListTail(&linkHead,20);
  298.                         break;
  299.                 case 3:
  300.                 //        printf("链表长度\n");
  301.                         printf("ListLength(L)=%d\n",ListLength(linkHead));
  302.                         break;
  303.                 case 4:
  304.                 //        printf("中间结点值\n");
  305.                         GetMidNode(linkHead,&e);
  306.                         printf("中间结点值:%d\n",e);
  307.                         break;
  308.                 case 5:
  309.                         ClearList(&linkHead);
  310.                         printf("ListLength(L)=%d\n",ListLength(linkHead));
  311.                         break;
  312.                 case 6:
  313.                         OverList(&linkHead);
  314.                         break;
  315.                 case 7:
  316.                         ListInsert(&linkHead,3,insert_e);
  317.                         PrintList(linkHead);
  318.                         break;
  319.                 case 8:
  320.                         ListDelete(&linkHead,5,&delsert_e);
  321.                         PrintList(linkHead);
  322.                         break;
  323.                 case 0:
  324.                         printf("退出\n");
  325.                         break;

  326.                 default:
  327.                         printf("无效的选择\n");
  328.                         OutMenu();
  329.                 }

  330.                 if(nSelect == 0)
  331.                 {
  332.                         break; //跳出while循环
  333.                 }
  334.         }

  335. ////////////////////////////////////////////////
  336. //        printf("\n");
  337. //        system("pause");
  338.         return 0;
  339. }

复制代码



错误的地方还请各位鱼油指正~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-20 18:12:06 | 显示全部楼层
谢谢分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-29 00:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表