`
weimou66
  • 浏览: 1240713 次
文章分类
社区版块
存档分类
最新评论

数据结构学习笔记

 
阅读更多

数据结构学习笔记(一)

假期以来我都坚持每天看一点郝斌的数据结构视频。讲的很透彻,也很风趣。

前几天都是为讲数据结构而做准备,讲了一些结构体和指针,今天终于开始正式将数据结构。说实话,我今天才知道函数的用处。。

照着郝斌讲连续存储数组的算法演示,又自己写了一遍,发现有一个错误,左看右看都看不出哪错了,索性贴出了,,,有兴趣的朋友可以看看

百度求助,一位牛人看出错误来,谢谢了!重新贴出正确的代码

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>//包含exit
  4. intval,i,t;
  5. structArr
  6. {
  7. int*pBase;//储存的是数组第一个元素的地址
  8. intlen;//数组所能容纳的最大元素个数
  9. intcnt;//当前数组有效个数
  10. };
  11. voidinit_arr(structArr*pArr,intlength);//初始化
  12. boolappend_arr(structArr*pArr,intval);
  13. boolinsert_arr(structArr*pArr,intpos,intval);//pos的值从1开始
  14. booldelete_arr(structArr*pArr,intpos,int*pVal);
  15. intget();
  16. boolis_empty(structArr*pArr);
  17. boolis_full(structArr*pArr);
  18. voidsort_arr(structArr*pArr);
  19. voidshow_arr(structArr*pArr);
  20. voidinversion_arr(structArr*pArr);//倒置
  21. intmain()
  22. {
  23. structArrarr;
  24. init_arr(&arr,6);
  25. show_arr(&arr);
  26. append_arr(&arr,1);
  27. append_arr(&arr,2);
  28. append_arr(&arr,3);
  29. append_arr(&arr,4);
  30. delete_arr(&arr,1,&val);
  31. return0;
  32. }
  33. voidinit_arr(structArr*pArr,intlength)
  34. {
  35. pArr->pBase=(int*)malloc(sizeof(int)*length);
  36. if(NULL==pArr->pBase)
  37. {
  38. printf("动态内存分配失败!\n");
  39. exit(-1);//终止整个程序
  40. }
  41. else
  42. {
  43. pArr->len=length;
  44. pArr->cnt=0;
  45. }
  46. return;
  47. }
  48. boolis_empty(structArr*pArr)
  49. {
  50. if(0==pArr->cnt)
  51. returntrue;
  52. else
  53. returnfalse;
  54. }
  55. boolis_full(structArr*pArr)
  56. {
  57. if(pArr->cnt==pArr->len)
  58. returntrue;
  59. else
  60. returnfalse;
  61. }
  62. voidshow_arr(structArr*pArr)
  63. {
  64. if(is_empty(pArr))//pArr本来就是地址
  65. {
  66. printf("数组为空\n");
  67. }
  68. else
  69. {
  70. for(inti=0;i<pArr->cnt;++i)
  71. printf("%d",pArr->pBase[i]);
  72. printf("\n");
  73. }
  74. }
  75. boolappend_arr(structArr*pArr,intval)
  76. {
  77. if(is_full(pArr))
  78. returnfalse;
  79. else
  80. pArr->pBase[pArr->cnt]=val;
  81. (pArr->cnt)++;
  82. returntrue;
  83. }
  84. boolinsert_arr(structArr*pArr,intpos,intval)
  85. {
  86. inti;
  87. if(pos<1||pos>pArr->len)
  88. for(i=pArr->cnt-1;i>=pos-1;--i)
  89. {
  90. pArr->pBase[i+1]=pArr->pBase[i];
  91. }
  92. pArr->pBase[pos-1]=val;
  93. returntrue;
  94. }
  95. booldelete_arr(structArr*pArr,intpos,int*pVal)
  96. {
  97. if(is_empty(pArr))
  98. returnfalse;
  99. if(pos<1||pos>pArr->cnt)
  100. returnfalse;
  101. *pVal=pArr->pBase[pos-1];
  102. for(i=pos;i<pArr->cnt;i++)
  103. {
  104. pArr->pBase[i-1]=pArr->pBase[i];
  105. }
  106. pArr->cnt--;
  107. returntrue;
  108. }
  109. voidinversion_arr(structArr*pArr)
  110. {
  111. inti=0;
  112. intj=pArr->cnt-1;
  113. intt;
  114. while(i<j)
  115. {
  116. t=pArr->pBase[i];
  117. pArr->pBase[i]=pArr->pBase[j];
  118. pArr->pBase[j]=t;
  119. i++;
  120. j--;
  121. }
  122. return;
  123. }
  124. voidsort_arr(structArr*pArr)
  125. {
  126. inti,j;//冒泡法
  127. for(i=0;i<pArr->cnt;i++)
  128. {
  129. for(j=i+1;j<pArr->cnt;i++)
  130. {
  131. if(pArr->pBase[i]>pArr->pBase[j])
  132. {
  133. t=pArr->pBase[i];
  134. pArr->pBase[i]=pArr->pBase[j];
  135. pArr->pBase[j]=t;
  136. }
  137. }
  138. }
  139. }



数据结构学习笔记(二)

今天看链表创建和链表遍历算法的演示,自己有照猫画虎写了一遍,遇到了1个错误,丢给M,还是他牛啊,火眼金睛一下就看出来了,贴出来,与大家分享

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. typedefstructNode
  5. {
  6. intdata;//数据域
  7. structNode*pNext;//指针域
  8. }NODE,*PNODE;//NODE等价于structNodeNODE,pNODE等价于structNode*
  9. PNODEcreate_list(void);
  10. voidtraverse_list(PNODEpHead);
  11. voidmain()
  12. {
  13. PNODEpHead=NULL;//等价于structNode*pHead=NULL
  14. pHead=create_list();//创建一个非循环链表,并将该链表的头地址赋给pHead
  15. traverse_list(pHead);
  16. }
  17. PNODEcreate_list(void)
  18. {
  19. intlen;
  20. inti;
  21. intval;//用来临时存放用户输入的结点的值
  22. PNODEpHead=(PNODE)malloc(sizeof(NODE));
  23. if(NULL==pHead)
  24. {
  25. printf("分配失败,程序终止!\n");
  26. exit(-1);
  27. }
  28. PNODEpTail=pHead;
  29. pTail->pNext=NULL;
  30. printf("请输入您需要生成的链表节点个数:len:");
  31. scanf("%d",&len);
  32. for(i=0;i<len;len++)
  33. {
  34. printf("请输入第%d个链表节点的值",i+1);
  35. scanf("%d",&val);
  36. PNODEpNew=(PNODE)malloc(sizeof(NODE));
  37. if(NULL==pHead)
  38. {
  39. printf("分配失败,程序终止!\n");
  40. exit(-1);
  41. }
  42. pNew->data=val;
  43. pTail->pNext=pNew;
  44. pNew->pNext=NULL;
  45. pTail=pNew;
  46. }
  47. returnpHead;
  48. }
  49. voidtraverse_list(PNODEpHead)
  50. {
  51. PNODEp=pHead->pNext;
  52. while(NULL!=p)
  53. {
  54. printf("%d",p->data);
  55. p=p->pNext;
  56. printf("\n");
  57. }
  58. return;
  59. }

数据结构学习笔记(三)

郁闷!真心听不懂了!敲出代码也是错!百度知道无人解答!不管了,贴出来下午出去散散心!
  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. typedefstructNode
  5. {
  6. intdata;//数据域
  7. structNode*pNext;//指针域
  8. }NODE,*PNODE;//NODE等价于structNodeNODE,pNODE等价于structNode*
  9. PNODEcreate_list(void);
  10. voidtraverse_list(PNODEpHead);
  11. boolis_empty(PNODEpHead);
  12. intlength_list(PNODE);
  13. boolinsert_list(PNODE,intpos,intval);//在pHead所指的链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且pos的值从1开始
  14. booldelete_list(PNODE,int,int*);
  15. voidsort_list(PNODEpHead);//排序
  16. voidmain()
  17. {
  18. PNODEpHead=NULL;//等价于structNode*pHead=NULL
  19. pHead=create_list();//创建一个非循环链表,并将该链表的头地址赋给pHead
  20. traverse_list(pHead);
  21. }
  22. PNODEcreate_list(void)
  23. {
  24. intlen;
  25. inti;
  26. intval;//用来临时存放用户输入的结点的值
  27. PNODEpHead=(PNODE)malloc(sizeof(NODE));
  28. if(NULL==pHead)
  29. {
  30. printf("分配失败,程序终止!\n");
  31. exit(-1);
  32. }
  33. PNODEpTail=pHead;
  34. pTail->pNext=NULL;
  35. printf("请输入您需要生成的链表节点个数:len:");
  36. scanf("%d",&len);
  37. for(i=0;i<len;len++)
  38. {
  39. printf("请输入第%d个链表节点的值",i+1);
  40. scanf("%d",&val);
  41. PNODEpNew=(PNODE)malloc(sizeof(NODE));
  42. if(NULL==pHead)
  43. {
  44. printf("分配失败,程序终止!\n");
  45. exit(-1);
  46. }
  47. pNew->data=val;
  48. pTail->pNext=pNew;
  49. pNew->pNext=NULL;
  50. pTail=pNew;
  51. }
  52. returnpHead;
  53. }
  54. voidtraverse_list(PNODEpHead)
  55. {
  56. PNODEp=pHead->pNext;
  57. while(NULL!=p)
  58. {
  59. printf("%d",p->data);
  60. p=p->pNext;
  61. printf("\n");
  62. }
  63. return;
  64. }
  65. boolis_empty(PNODEpHead)
  66. {
  67. if(NULL==pHead->pNext)
  68. returntrue;
  69. else
  70. returnfalse;
  71. }
  72. intlength_list(PNODE)
  73. {
  74. PNODEp=pHead->pNext;
  75. intlen=0;
  76. while(NULL!=p)
  77. {
  78. ++len;
  79. p=p->pNext;
  80. }
  81. returnlen;
  82. }
  83. voidsort_list(PNODEpHead)
  84. {
  85. inti,j,t,len=0;
  86. PNODEp,q;
  87. for(i=0,p=pHead->pNext;i<len-1;++i,p=p->pNext)
  88. {
  89. for(j=i+1,q=p->pNext;j<len;++j,q=q->pNext)
  90. {
  91. if(p->data>q->data)//类似于数组中的:a[i]>a[j]
  92. {
  93. t=p->data;//t=a[i];
  94. p->data=q->data;//a[i]=a[j];
  95. q->data=t;//a[j]=t;
  96. }
  97. }
  98. }
  99. return;
  100. }
  101. boolinsert_list(PNODE,intpos,intval)
  102. {
  103. inti=0;
  104. PNODEp=pHead;
  105. while(NULL!=p&&i<pos-1)
  106. {
  107. p=p->pNext;
  108. ++i;
  109. }
  110. if(i>pos-1||NULL==p)
  111. returnfalse;
  112. PNODEpNew=(PNODE)malloc(sizeof(NODE));
  113. if(NULL==pNew)
  114. {
  115. printf("动态内存分配失败!\n");
  116. exit(-1);
  117. }
  118. pNew->data=val;
  119. PNODEq=p->pNext;
  120. p->pNext=pNew;
  121. pNew->pNext=q;
  122. returntrue;
  123. }
  124. booldelete_list(PNODE,intpos,int*val)
  125. {
  126. inti=0;
  127. PNODEp=pHead;
  128. while(NULL!=p&&i<pos-1)
  129. {
  130. p=p->pNext;
  131. ++i;
  132. }
  133. if(i>pos-1||NULL==p)
  134. returnfalse;
  135. PNODEq=p->pNext;
  136. *pVal=q->data;
  137. //删除p节点后面的结点
  138. PNODEq=p->pNext->pNext;
  139. free(q);
  140. q=NULL;
  141. returntrue;
  142. }

数据结构学习阶段总结(一)

数据结构

狭义

数据结构是专门研究数据存储问题

数据的存储包含两个方面:个体的存储 + 个体关系的存储

广义

数据结构既包括数据存储也包括数据的操作

对存储数据的操作就是算法

算法

狭义

算法是和数据存储方式密切相关

广义

算法和数据的存储方式无关

数据的存储结构

线性

连续存储【数组】

参照数据结构学习笔记(一)

优点 存取速度很快

缺点 插入删除元素很慢

空间通常有限制

必须知道数组长度

需要大块连续内存

离散存储【链表】

参照数据结构学习笔记(三)

优点 空间没有限制

插入删除元素很快

缺点 存取速度很慢

线性结构的应用--栈

线性结构的应用--队列

非线性

树,图

顺序存储结构的插入与删除

看了几个例子,心中有了些底子,把前面有些程序分割开,慢慢写出来。

插入算法思路:

1.如果插入不合理,抛出异常;

2.如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;

3.从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;

4.将要插入元素填入位置i处;

5.表长加1.

  1. //在L中第i个位置之前插入新元素e,L的长度加1
  2. intlistinsert(Sqlist*L,inti,ElemTypee)
  3. {
  4. intk;
  5. if(L->length==MAXSIZE)
  6. returnERROR;
  7. if(i<1||i>L->length+1)
  8. returnERROR;
  9. if(i<=L->length)
  10. {
  11. for(k=L->length-1;k>=i;k--)//后移一位
  12. L->data[k+1]=L->data[k];
  13. }
  14. L->data[i-1]=e;//插入
  15. L->Length++;
  16. returnOK;
  17. }


一样以来,简单明了。

删除算法思路不给出来了,和插入大同小异,给上代码

  1. //删除L中第i个元素,并用e返回其值,L长度减1
  2. intlistDelete(Sqlist*L,inti,ElemTypee)
  3. {
  4. intk;
  5. if(L->length==0)
  6. returnERROR;
  7. if(i<1||i>L->length)
  8. returnERROR;
  9. *e=L->data[i-1];
  10. if(i<=L->length)
  11. {
  12. for(k=i;k<=L->length;k++)//前移一位
  13. L->data[k-1]=L->data[k];
  14. }
  15. L->length--;
  16. returnOK;
  17. }

单链表的插入与删除

顺序结构的缺点还是蛮大的,现在来看看单链表的插入与删除。

单链表中,在C语言可以用结构体指针描述:

  1. typedefstructNode
  2. {
  3. ElemTypedata;
  4. structNode*next;//p->data,p->next->data
  5. }Node;
  6. typedefstructNode*LinkList


有一点很重要

比如我随便画一个。。

千万别也成

p->next=s;s->netx=p->next;

正确的是

s->netx=p->next;p->next=s;

自己好好想想,不打了。记得是逆序就行了~

好,进入正题,单链表第i个数据插入节点的算法思路:

1.声明一节点p指向链表第一个结点,初始化j从1开始;

2.当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;

3.若到链表末尾p为空,则说明第i个元素不存在;

4.否则查找成功,在系统中生成一个空节点s;

5.将数据元素e赋给s->data;

6.单链表插入标准语句s->next=p->next;p->next=s;

7.返回成功。

实现代码算法如下:

  1. //在L中第i个位置之前插入新的数据元素e,L的长度加1
  2. intListInsert(LinkList*L,inti,ElmeTypee)
  3. {
  4. intj;
  5. LinkListp,s;
  6. p=*L;
  7. j=1;
  8. while(p&&j<1)
  9. {
  10. p=p->next;
  11. ++j;
  12. }
  13. if(!p||j>=1)
  14. returnERROR;
  15. s=(LinkList)malloc(sizeof(Node));//生成新节点
  16. s->data=e;
  17. s->next=p->next;
  18. p->next=s;//顺序绝对不变
  19. returnOK;
  20. }


如何删除呢?其实只要q=p->next;p->next->q->next;

算法思路省略,直接给出代码:

  1. //删除L第i个元素,并用e返回其值,L的长度减1
  2. intListInsert(LinkList*L,inti,ElmeTypee)
  3. {
  4. intj;
  5. LinkListp,s;
  6. p=*L;
  7. j=1;
  8. while(p&&j<1)
  9. {
  10. p=p->next;
  11. ++j;
  12. }
  13. if(!(p->next)||j>=1)
  14. returnERROR;
  15. q=p->next;
  16. p->next=q->next;
  17. *e=q->data;
  18. free(q);//释放内存
  19. returnOK;
  20. }

单链表的整表创建--头插法,尾插法

创建单链表的过程是一个动态生成链表的过程。应依次建立各个结点,并逐个插入链表
给出头插法

  1. //随机产生n个元素的值,建立代表头结点的单链线性表L(头插法)
  2. voidCreateListHead(LinkList*L,intn)
  3. {
  4. LinkListp;
  5. inti;
  6. srand(time(0));//随机产生数
  7. *L=(LinkList)malloc(sizeof(Node));
  8. (*L)->next=NULL;//先建立一个带头结点的单链表
  9. for(i=0;i<n;i++)
  10. {
  11. p=(LinkList)malloc(sizeof(Node));//生成新结点
  12. p->data=rand()%100+1;//随机生成1001以内的数字
  13. p->next=(*L)->netx;
  14. (*L)->next=p;//插入到表头
  15. }
  16. }


尾插法:

  1. //随机产生n个元素的值,建立代表头结点的单链线性表L(头插法)
  2. voidCreateListTail(LinkList*L,intn)
  3. {
  4. LinkListp,r;
  5. inti;
  6. srand(time(0));//随机产生数
  7. *L=(LinkList)malloc(sizeof(Node));
  8. r=*L;
  9. for(i=0;i<n;i++)
  10. {
  11. p=(LinkList)malloc(sizeof(Node));//生成新结点
  12. p->data=rand()%100+1;//随机生成1001以内的数字
  13. r->next=p;//将表尾终端结点指向新结点
  14. r=p;//将当前新结点定义为表尾终端结点
  15. }
  16. r->next=NULL;//表示当前链表结束
  17. }

单链表的整表删除

单链表的整表删除,先写一些算法思路

1.声明一节点p和q;

2.将第一个结点赋值给p;

3.循环:

将下一结点赋值给q;

释放p;

将q赋值给p;

给出代码:
  1. boolclearList(LinkList*L)
  2. {
  3. LinkListp,q;
  4. p=(*L)->next;
  5. while(p)
  6. {
  7. q=p->next;
  8. free(p);
  9. p=q;
  10. }
  11. (*L)->next=NULL;
  12. returnOK;
  13. }

用数组组成的链表--静态链表

C语言有指针,可以按照上次那个方法做一下,但JAVA,C#,Basic呢?怎么办?前辈们真是聪明,用数组描述指针。这个数组由两部分组成,一个位DATA域,一个位CUR指针域

线性表的静态链表存储结构

  1. typedefstruct
  2. {
  3. ElemTypedata;
  4. intcur;/*游标(Cursor),为0时表示无指向*/
  5. }Component,StaticLinkList[MAXSIZE];


静态链表的插入

  1. /*在L中第i个元素之前插入新的数据元素e*/
  2. StatusListInsert(StaticLinkListL,inti,ElemTypee)
  3. {
  4. intj,k,l;
  5. k=MAXSIZE-1;/*注意k首先是最后一个元素的下标*/
  6. if(i<1||i>ListLength(L)+1)
  7. returnERROR;
  8. j=Malloc_SSL(L);/*获得空闲分量的下标*/
  9. if(j)
  10. {
  11. L[j].data=e;/*将数据赋值给此分量的data*/
  12. for(l=1;l<=i-1;l++)/*找到第i个元素之前的位置*/
  13. k=L[k].cur;
  14. L[j].cur=L[k].cur;/*把第i个元素之前的cur赋值给新元素的cur*/
  15. L[k].cur=j;/*把新元素的下标赋值给第i个元素之前元素的ur*/
  16. returnOK;
  17. }
  18. returnERROR;
  19. }


静态链表的元素删除

  1. /*删除在L中第i个数据元素*/
  2. StatusListDelete(StaticLinkListL,inti)
  3. {
  4. intj,k;
  5. if(i<1||i>ListLength(L))
  6. returnERROR;
  7. k=MAXSIZE-1;
  8. for(j=1;j<=i-1;j++)
  9. k=L[k].cur;
  10. j=L[k].cur;
  11. L[k].cur=L[j].cur;
  12. Free_SSL(L,j);
  13. returnOK;
  14. }

数据结构

狭义

数据结构是专门研究数据存储问题

数据的存储包含两个方面:个体的存储 + 个体关系的存储

广义

数据结构既包括数据存储也包括数据的操作

对存储数据的操作就是算法

算法

狭义

算法是和数据存储方式密切相关

广义

算法和数据的存储方式无关

数据的存储结构

线性

连续存储【数组】

参照数据结构学习笔记(一)

优点 存取速度很快

缺点 插入删除元素很慢

空间通常有限制

必须知道数组长度

需要大块连续内存

离散存储【链表】

参照数据结构学习笔记(三)

优点 空间没有限制

插入删除元素很快

缺点 存取速度很慢

线性结构的应用--栈

线性结构的应用--队列

非线性

树,图

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics