数据结构 大O表示法和顺序表

来源:互联网 发布:有哪些好的p2p平台知乎 编辑:程序博客网 时间:2024/05/22 14:43
1.数据之间的逻辑结构:
   集合结构:数据元素之间没有特别的关系,仅同属相同集合
   线性结构:数据元素之间是一对一的关系
   树形结构:数据元素之间存在一对多的层次关系
   图形结构:数据元素之间是多对多的关系
2.数据之间的物理结构
    顺序存储结构:将数据存储在地址连续的存储单元里
    链式存储结构:将数据存储在任意的存储单元里,通过保存地址的方式找到相关的数据元素
3.数据结构是相互之间存在一种或多种特定关系的数据元素的集合
4.程序 = 数据结构 + 算法
5.大O表示法:算法效率严重依赖于操作数量,首先关注操作数的最高次项,操作数的估计可以作为时间和空间复杂度的估算,在没有特殊说明的时候,我们应该分析复杂度的最坏情况
6.常见的复杂度类型:
大小关系:
7.线性表是零个或多个数据元素的集合,之间的元素是有顺序的,个数是有限的,数据类型必须相同。线性表包含两种存储方式,一种是顺序表,另一种链表。
8.对于线性表的使用是这样的:应该是在设计算法的时候,考虑算法中使用的数据,这些数据之间是什么关系的,如果是符合线性表特质的,就选择线性表作为数据结构。
9.顺序表与数组的关系:其实顺序表就是在数组的基础上构建的,本质跟数组是一样的,只是在数组的基础上增加了length长度,capacity容量等特性,然后补充了一些列,增、删、改、查的功能。
10. 我觉得链表比顺序表最大的优势,就在于链表的删除和插入要比顺序表简单的多,而且当线性表长度很大的时候很难开辟出整段的连续空间!!!最重要的是顺序表在创建的时候长度就固定了,再也改变不了了,而链表则可以根据情况动态增加,这一点是顺序表无论怎么样都不可能实现的!!!
 
顺序表的优点是:无需为线性表中的逻辑增加额外的空间,可以快速的通过下标的方式找到表中的合法位置。
11.线性表的常用操作:创建线性表、销毁线性表、清空线性表、将元素插入线性表、将元素从线性表中删除、获取线性表中某个位置的元素、获取线性表的长度

本节代码:

1.本节的代码是一个可以适合各种类型的顺序表,之所以能够适合各种类型,是因为它在顺序表中保存的是元素的地址(其实就是一个指针数组)。
2.代码中的描述顺序表的结构体中的元素介绍:length是顺序表中有元素的个数、capacity是顺序表的容量、node是顺序表的头地址(也是这个指针数组的头地址)、还有一个就是pos,pos是在删除和插入的时候使用的一个参数,它代表的是插入到顺序表位置的下标(数组的下标 是从0开始的 这个很要注意)。顺序表中有length个元素 下标是从0到length-1的。要注意的是 操作顺序表不同功能函数的pos的允许范围是不一样的。
3.本节代码对于函数参数的合法性判断是极其重视的,这个规范是值得学习的。
4.本节代码中对于顺序表的操作函数,凡是外界输入的,和输出到外界的,都是void *类型的,这样就保证了只有在这些操作函数中才能去改变   描述顺序表的结构体里面的值,在其他文件的函数中接受到的都是void *类型,无法直接给这个结构体中的值进行改变,这样的封装,保证了代码的安全性。
5.对于本节代码最值得思考的地方,常见的顺序表是typedef一个A类型,然后在顺序表中定义一个这个A类型的数组和length顺序表元素个数,这个顺序表中是好多个A类型的顺序集合,占用空间的大小是sizeof(A)*capacity。而本节的顺序表中是好多个unsigned int *地址类型的顺序集合,表中只有地址,第一节省了顺序表的空间,第二这样可以变相的保存不同类型的数据,第三它实现了 顺序表(即数据结构) 和 我们打算利用的数据(即元素)的分离。例如:linux内核链表(一个双向循环链表)就是一套单独的链表体制,这个链表用在很多机制上面,它就是变相的存储了好多类型的数据,并且实现了链表和数据的分离。
所以在main.c中  数据要想保存在这个顺序表中  就应该先给这些数据开辟内存    因为顺序表中没有他们呆的地方   顺序表中只能保存他们的地址。
如图:
代码如下:
Seqlist.c:
[cpp] view plaincopy
  1. /************************************************************************************  
  2. 文件名:Seqlist.c 
  3. 头文件:Seqlist.h  
  4. 时间: 2013/08/05  
  5. 作者: Hao  
  6. 功能:可以复用 带有增 删 改 查 功能的顺序表 
  7. 难点:1.顺序表中存放的都是 各种数据的地址 
  8.       2.void *是用来隔离封装用的 保证顺序表结构体只能被特定的函数改变                                                                                                                                  
  9. ************************************************************************************/  
  10. #include <stdio.h>  
  11. #include <malloc.h>  
  12. #include "Seqlist.h"  
  13.   
  14. typedef unsigned int TSeqListNode;//这个顺序表中存放的是 各种数据的地址 所以用unsigned int   
  15. typedef struct str_SeqList  
  16. {  
  17.     int length;//顺序已用的长度   
  18.     int capacity;//顺序表的总容量   
  19.     TSeqListNode* node;//这个指针是用来在顺序表中游走读取数据用的   
  20. }TSeqList;  //定义描述顺序表的结构体   
  21.   
  22. /************************************************************************************  
  23. 函数名:   Creat_SeqList 
  24. 函数功能: 创建一个容量为capacity的顺序表  
  25. 参数:     int capacity 创建顺序表中成员的个数 即顺序表容量 
  26. 返回值:   void* ret 如果返回NULL 说明创建顺序表失败 
  27.                      如果返回ret 说明创建顺序表成功  且ret为描述顺序表的结构体  
  28. ************************************************************************************/  
  29. SeqList* Creat_SeqList(int capacity)  
  30. {  
  31.     TSeqList* ret = NULL;  
  32.     /*进入函数 第一点是先判断传人参数的合法性*/  
  33.     if(capacity >= 0)  
  34.     {  
  35.         /*给顺序表开辟空间*/  
  36.         ret=(TSeqList* )malloc(sizeof(TSeqList)+sizeof(TSeqListNode)*capacity);  
  37.         if(NULL!=ret)//空间开辟成功   给描述顺序表的结构体 赋值   
  38.         {  
  39.             ret->capacity=capacity;  
  40.             ret->length=0;  
  41.             ret->node=(TSeqListNode* )(ret+1);//把真正顺序表的地址赋给 node   
  42.         }  
  43.     }  
  44.     else  
  45.     {  
  46.         ret = NULL;  
  47.     }   
  48.     return (SeqList*)(ret);  
  49. }   
  50.   
  51. /************************************************************************************  
  52. 函数名:   Destroy_SeqList 
  53. 函数功能: 销毁顺序表   free开辟的内存  
  54. 参数:     void* list 描述顺序表结构体指针 
  55. 返回值:   void  
  56. ************************************************************************************/  
  57. void  Destroy_SeqList(SeqList* list)  
  58. {  
  59.     free(list);  
  60. }  
  61.   
  62. /************************************************************************************  
  63. 函数名:  Get_Seqlist_Length 
  64. 函数功能:获得顺序表 现在的大小 
  65. 函数参数:void* list 描述顺序表结构体指针 
  66. 函数返回值:int ret  成功返回length 
  67.                      失败返回-1  
  68. ************************************************************************************/  
  69. int Get_Seqlist_Length(SeqList* list)  
  70. {  
  71.     int ret;  
  72.     TSeqList *Tlist=(TSeqList* )list;  
  73.     /*函数参数合法性检测*/  
  74.     if(NULL != Tlist)  
  75.     {  
  76.         ret=Tlist->length;  
  77.     }   
  78.     else  
  79.         ret=-1;  
  80.     return ret;  
  81. }  
  82.   
  83. /************************************************************************************ 
  84. 函数名:  Get_Seqlist_Capacity 
  85. 函数功能:获得顺序表 的容量  
  86. 函数参数:void* list 描述顺序表结构体指针 
  87. 函数返回值:int ret  成功返回capacity  
  88.                      失败返回-1  
  89. ************************************************************************************/  
  90. int Get_Seqlist_Capacity(SeqList* list)  
  91. {  
  92.     int ret;  
  93.     TSeqList *Tlist=(TSeqList* )list;  
  94.     /*函数参数合法性检测*/  
  95.     if(NULL != Tlist)  
  96.     {  
  97.         ret = Tlist->capacity;  
  98.     }   
  99.     else  
  100.         ret=-1;  
  101.     return ret;  
  102. }  
  103.   
  104. /************************************************************************************  
  105. 函数名:  Clean_Seqlist_Length 
  106. 函数功能:清空顺序表  其实就是给length=0;  
  107. 函数参数:void* list 描述顺序表结构体指针 
  108. 函数返回值:int ret  成功返回0 
  109.                      失败返回-1  
  110. ************************************************************************************/  
  111. int Clean_Seqlist_Length(SeqList* list)  
  112. {  
  113.     int ret;  
  114.     TSeqList *Tlist=(TSeqList* )list;  
  115.     /*函数参数合法性检测*/  
  116.     if(NULL != Tlist)  
  117.     {  
  118.         Tlist->length=0;  
  119.         ret=0;  
  120.     }   
  121.     else  
  122.         ret=-1;  
  123.     return ret;  
  124. }  
  125.   
  126. /************************************************************************************ 
  127. 函数名:  Seqlist_Add 
  128. 函数功能:顺序表中有length个数据  在下标为pos的位置上 插入数据node  所以pos是从0开始的 length是从1开始的  
  129. 参数:      SeqList* list描述顺序表的结构体地址   SeqListNode* node插入顺序表的数据的地址   
  130.            int pos插入顺序表的位置   pos的范围是从0(此时在顺序表头部插入)开始  到length(此时就是在顺序尾部插入) 
  131.             总共是length+1个位置  
  132. 返回值 :  返回1 说明插入数据成功  返回0 说明插入数据失败 
  133. ************************************************************************************/  
  134. int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos)  
  135. {  
  136.     /*参数合法性检测*/  
  137.     TSeqList *Tlist=(TSeqList* )list;  
  138.     int ret = (NULL != list);  
  139.     int i;  
  140.     ret=ret && (pos >= 0);  
  141.     ret=ret && (Tlist->length+1 <= Tlist->capacity);  //判断再插入一个数据的时候  length有没有超过 capacity   
  142.     if(1 == ret)  
  143.     {  
  144.         if(pos >= Tlist->length)//如果插入的位置pos比 length大的话 默认把length+1赋值给pos   
  145.         {  
  146.             pos = Tlist->length;  
  147.         }  
  148.         for(i=Tlist->length;i>pos;i--)  
  149.         {  
  150.             Tlist->node[i]=Tlist->node[i-1];  
  151.         }   
  152.         Tlist->node[i]=(TSeqListNode)node; //把要插入的地址强制类型转换成 unsigned int*   
  153.         Tlist->length++;  
  154.     }   
  155.     return ret;//返回1 说明插入数据成功  返回0 说明插入数据失败   
  156. }     
  157.   
  158.    
  159. /************************************************************************************ 
  160. 函数名:   Get_Node 
  161. 函数功能:找到顺序表中下标为pos的值   
  162. 参数:    pos插入顺序表的下标   pos的范围是从0到length-1    
  163.           SeqList* list描述顺序表的结构体地址 
  164. 返回值:  void* ret 找到pos为下标的那个值 
  165.         如果成功返回pos为下标的那个值   如果失败  返回NULL 
  166. ************************************************************************************/  
  167.   
  168. SeqListNode* Get_Node(SeqList* list, int pos)  
  169. {  
  170.     TSeqList* Tlist=(TSeqList* )list;  
  171.     SeqListNode* ret=NULL;  
  172.     if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )  
  173.     {  
  174.         ret=(SeqListNode* )Tlist->node[pos]; //强制类型转换成void*    
  175.     }  
  176.     return ret;  
  177. }   
  178.   
  179. /************************************************************************************ 
  180. 函数名:   Del_Node 
  181. 函数功能:找到顺序表中下标为pos的值  并且删除它  
  182. 参数:    删除pos为下标的值   pos的范围是从0到length-1    
  183.           SeqList* list描述顺序表的结构体地址 
  184. 返回值:  void* ret  
  185.           如果成功返回pos为下标的那个值   如果失败  返回NULL  
  186. ************************************************************************************/  
  187. SeqListNode* Del_Node(SeqList* list, int pos)  
  188. {  
  189.     TSeqList* Tlist=(TSeqList* )list;  
  190.     SeqListNode* ret=NULL;  
  191.     int i;  
  192.     if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )  
  193.     {  
  194.         ret=(SeqListNode* )Tlist->node[pos];  
  195.         for(i=pos+1; i<Tlist->length; i++)  
  196.         {  
  197.             Tlist->node[i-1]=Tlist->node[i];  
  198.         }  
  199.         Tlist->length--;  
  200.     }  
  201.     return ret;  
  202. }  

Seqlist.h:
[cpp] view plaincopy
  1. #ifndef __Seqlist__  
  2. #define __Seqlist__  
  3.   
  4. typedef void SeqList;  //是用来封装 使顺序表结构体 不被外界改变 只可被Seqlist.c文件中的函数改变  
  5.                        //因为 这些函数 对外的接口 都是void*    
  6. typedef void SeqListNode;//SeqList 是用来表示 顺序表的    SeqListNode是用来表示顺序表 中变量的   
  7.   
  8. SeqList* Creat_SeqList(int capacity);  
  9. void  Destroy_SeqList(SeqList* list);  
  10. int Get_Seqlist_Length(SeqList* list);  
  11. int Get_Seqlist_Capacity(SeqList* list);  
  12. int Clean_Seqlist_Length(SeqList* list);  
  13. int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos);  
  14. SeqListNode* Get_Node(SeqList* list, int pos);  
  15. SeqListNode* Del_Node(SeqList* list, int pos);   
  16.   
  17. #endif  

main.c:
[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "Seqlist.h"  
  4. int main(int argc, char *argv[])  
  5. {  
  6.     SeqList* My_SeqList = NULL;  
  7.     int a = 10;  
  8.     int b = 5;  
  9.     int c = 3;  
  10.     int d = 6;  
  11.     int e = 1;  
  12.     int *p = NULL;  
  13.     int i = 0;  
  14.     My_SeqList = Creat_SeqList(5);  
  15.     if( NULL != My_SeqList )  
  16.     {  
  17.             Seqlist_Add(My_SeqList, &a ,0);  
  18.             Seqlist_Add(My_SeqList, &b ,0);  
  19.             Seqlist_Add(My_SeqList, &c ,0);  
  20.             Seqlist_Add(My_SeqList, &d ,0);  
  21.             Seqlist_Add(My_SeqList, &e ,0);  
  22.               
  23.             for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)  
  24.             {  
  25.                 p=Get_Node(My_SeqList, i);  
  26.                 printf("%d\n",*p);  
  27.             }  
  28.               
  29.             Del_Node(My_SeqList, 3);  
  30.             for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)  
  31.             {  
  32.                 p=Get_Node(My_SeqList, i);  
  33.                 printf("%d\n",*p);  
  34.             }  
  35.               
  36.     }   
  37.     Clean_Seqlist_Length(My_SeqList);  
  38.     Destroy_SeqList(My_SeqList);  
  39.     return 0;  
  40. }  


test_main.c:
[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <malloc.h>  
  4. #include "Seqlist.h"  
  5.   
  6. typedef struct student  
  7. {  
  8.     int student_num;  
  9.     char name[30];  
  10.     char sex[20];  
  11.     int age;  
  12. }str;  
  13. int main()  
  14. {  
  15.     str* str1;  
  16.     SeqList* slist=NULL;  
  17.     int i=0;  
  18.     int age=0;  
  19.     slist=Creat_SeqList(50);  
  20.     if(NULL == slist)  
  21.     {  
  22.         printf("malloc error!!!\n");  
  23.         return -1;  
  24.     }  
  25.     for(i=0; i<3; i++)  
  26.     {  
  27.         put_student(slist, str1);  
  28.     }  
  29.       
  30.     printf("输入你要删除的年龄:\n");  
  31.     scanf("%d",&age);  
  32.     printf("\n");  
  33.     find_student(slist, str1, age);  
  34.     get_student(slist, str1);  
  35.       
  36.     destroy_student(slist, str1);  
  37.     Clean_Seqlist_Length(slist);  
  38.     Destroy_SeqList(slist);  
  39.     return 0;  
  40. }  
  41.   
  42. int put_student(SeqList* slist, str* str1)  
  43. {   
  44.     int num;  
  45.     int ret=(NULL != str1);  
  46.     if(1 == ret)  
  47.     {  
  48.         ret=ret && Seqlist_Add(slist, (str* )malloc(sizeof(str)*1) ,50);  
  49.         num = Get_Seqlist_Length(slist);  
  50.         str1 = (str* )Get_Node(slist, num-1);  
  51.         printf("请输入学生学号:\n");   
  52.         scanf("%d",&str1->student_num);  
  53.         printf("请输入学生姓名:\n");  
  54.         scanf("%s",str1->name);  
  55.         printf("请输入学生性别:\n");  
  56.         scanf("%s",str1->sex);  
  57.         printf("请输入学生年龄:\n");  
  58.         scanf("%d",&str1->age);  
  59.         printf("\n");   
  60.     }         
  61.     else  
  62.     {  
  63.         ret = 0;  
  64.     }  
  65.     return ret;  
  66. }  
  67.   
  68. int get_student(SeqList* slist, str* str1)  
  69. {  
  70.     int ret=(NULL != str1);  
  71.     int i=0;  
  72.     if(1 == ret)  
  73.     {  
  74.         for(i=0; i<Get_Seqlist_Length(slist); i++)  
  75.         {  
  76.             str1 = (str*)Get_Node(slist, i);  
  77.             printf("学生学号:%d\n",str1->student_num);  
  78.           
  79.             printf("学生姓名:%s\n",str1->name);  
  80.               
  81.             printf("学生性别:%s\n",str1->sex);  
  82.               
  83.             printf("学生年龄:%d\n",str1->age);  
  84.         }  
  85.     }         
  86.     else  
  87.     {  
  88.         ret = 0;  
  89.     }  
  90.     return ret;  
  91. }  
  92.   
  93. int destroy_student(SeqList* slist, str* str1)  
  94. {  
  95.     int ret=(NULL != str1);  
  96.     int i=0;  
  97.     if(1 == ret)  
  98.     {  
  99.         for(i=0; i<Get_Seqlist_Length(slist); i++)  
  100.         {  
  101.             str1 = (str*)Get_Node(slist, i);  
  102.             free(str1);  
  103.         }  
  104.     }         
  105.     else  
  106.     {  
  107.         ret = 0;  
  108.     }  
  109.     return ret;  
  110. }  
  111.   
  112. int find_student(SeqList* slist, str* str1, int age)  
  113. {  
  114.     int ret=(NULL != str1);  
  115.     int i=0;  
  116.     int num=0;  
  117.     if(1 == ret)  
  118.     {  
  119.         num=Get_Seqlist_Length(slist);  
  120.         for(i=0; i<num; i++)  
  121.         {  
  122.             str1 = (str*)Get_Node(slist, i);  
  123.             if(str1->age == age)  
  124.             {  
  125.                 Del_Node(slist, i);  
  126.                 num=Get_Seqlist_Length(slist);  
  127.                 i--;  
  128.             }  
  129.         }  
  130.     }         
  131.     else  
  132.     {  
  133.         ret = 0;  
  134.     }  
  135.     return ret;  
  136. }  

test_main.c:
[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <malloc.h>  
  4. #include "Seqlist.h"  
  5.   
  6. typedef struct student  
  7. {  
  8.     int student_num;  
  9.     char name[30];  
  10.     char sex[20];  
  11.     int age;  
  12. }str;  
  13. int main()  
  14. {  
  15.     str* str1;  
  16.     SeqList* slist=NULL;  
  17.     int i=0;  
  18.     int age=0;  
  19.     slist=Creat_SeqList(50);  
  20.     if(NULL == slist)  
  21.     {  
  22.         printf("malloc error!!!\n");  
  23.         return -1;  
  24.     }  
  25.     for(i=0; i<3; i++)  
  26.     {  
  27.         put_student(slist, str1);  
  28.     }  
  29.       
  30.     printf("输入你要删除的年龄:\n");  
  31.     scanf("%d",&age);  
  32.     printf("\n");  
  33.     find_student(slist, str1, age);  
  34.     get_student(slist, str1);  
  35.       
  36.     destroy_student(slist, str1);  
  37.     Clean_Seqlist_Length(slist);  
  38.     Destroy_SeqList(slist);  
  39.     return 0;  
  40. }  
  41.   
  42. int put_student(SeqList* slist, str* str1)  
  43. {   
  44.     int num;  
  45.     int ret=(NULL != str1);  
  46.     if(1 == ret)  
  47.     {  
  48.         ret=ret && Seqlist_Add(slist, (str* )malloc(sizeof(str)*1) ,50);  
  49.         num = Get_Seqlist_Length(slist);  
  50.         str1 = (str* )Get_Node(slist, num-1);  
  51.         printf("请输入学生学号:\n");   
  52.         scanf("%d",&str1->student_num);  
  53.         printf("请输入学生姓名:\n");  
  54.         scanf("%s",str1->name);  
  55.         printf("请输入学生性别:\n");  
  56.         scanf("%s",str1->sex);  
  57.         printf("请输入学生年龄:\n");  
  58.         scanf("%d",&str1->age);  
  59.         printf("\n");   
  60.     }         
  61.     else  
  62.     {  
  63.         ret = 0;  
  64.     }  
  65.     return ret;  
  66. }  
  67.   
  68. int get_student(SeqList* slist, str* str1)  
  69. {  
  70.     int ret=(NULL != str1);  
  71.     int i=0;  
  72.     if(1 == ret)  
  73.     {  
  74.         for(i=0; i<Get_Seqlist_Length(slist); i++)  
  75.         {  
  76.             str1 = (str*)Get_Node(slist, i);  
  77.             printf("学生学号:%d\n",str1->student_num);  
  78.           
  79.             printf("学生姓名:%s\n",str1->name);  
  80.               
  81.             printf("学生性别:%s\n",str1->sex);  
  82.               
  83.             printf("学生年龄:%d\n",str1->age);  
  84.         }  
  85.     }         
  86.     else  
  87.     {  
  88.         ret = 0;  
  89.     }  
  90.     return ret;  
  91. }  
  92.   
  93. int destroy_student(SeqList* slist, str* str1)  
  94. {  
  95.     int ret=(NULL != str1);  
  96.     int i=0;  
  97.     if(1 == ret)  
  98.     {  
  99.         for(i=0; i<Get_Seqlist_Length(slist); i++)  
  100.         {  
  101.             str1 = (str*)Get_Node(slist, i);  
  102.             free(str1);  
  103.         }  
  104.     }         
  105.     else  
  106.     {  
  107.         ret = 0;  
  108.     }  
  109.     return ret;  
  110. }  
  111.   
  112. int find_student(SeqList* slist, str* str1, int age)  
  113. {  
  114.     int ret=(NULL != str1);  
  115.     int i=0;  
  116.     int num=0;  
  117.     if(1 == ret)  
  118.     {  
  119.         num=Get_Seqlist_Length(slist);  
  120.         for(i=0; i<num; i++)  
  121.         {  
  122.             str1 = (str*)Get_Node(slist, i);  
  123.             if(str1->age == age)  
  124.             {  
  125.                 Del_Node(slist, i);  
  126.                 num=Get_Seqlist_Length(slist);  
  127.                 i--;  
  128.             }  
  129.         }  
  130.     }         
  131.     else  
  132.     {  
  133.         ret = 0;  
  134.     }  
  135.     return ret;  
  136. }  

原创粉丝点击