顺序表的基本操作

来源:互联网 发布:js仿ios选择器 编辑:程序博客网 时间:2024/06/02 02:31

1.基本定义

[cpp] view plain copy
  1. #include<stdio.h>  
  2. //顺序表:1.使用动态分配的一维数组  
  3. //        2.使用静态分配的一维数组  
  4. //本实例使用静态分配  
  5. #define LIST_INIT_SIZE 100  
  6. typedef int ElemType;  
  7.   
  8. typedef struct SqList{  
  9.     ElemType data[LIST_INIT_SIZE];  
  10.     int len;  
  11. }SqList;  

2.创建线性表和打印输出线性表

[cpp] view plain copy
  1. //创建一个长度为n的顺序线性表  
  2. void createSqList(SqList &L, int n){  
  3.     printf("请输入%d个数:\n", n);  
  4.     for(int i = 0; i < n; i++){  
  5.         scanf("%d",&L.data[i]);  
  6.     }  
  7.     L.len = n;  
  8.     //printSqList(L);  
  9. }  

[cpp] view plain copy
  1. //打印输出顺序线性表  
  2. void printSqList(SqList L){  
  3.     printf("打印线性表:");  
  4.     for(int i = 0; i < L.len; i++){  
  5.         printf("%d ",L.data[i]);  
  6.     }  
  7.     printf("\n");  
  8. }  

[cpp] view plain co
[cpp] view plain copy
  1. void main(){  
  2.       
  3.     //初始化一个空的线性表  
  4.     SqList L;  
  5.     L.len=0;  
  6.       
  7.     createSqList(L, 5);//创建一个线性表  
  8.     printSqList(L);  
  9. }  

3.插入操作

[cpp] view plain copy
  1. //在第i(1<=i<=n)个元素之前插入一个元素,需要向后移动n-i+1个元素,  
  2. //在最后插入则不需要移动任何元素,可供插入的位置有n+1个,  
  3. //从后往前找插入的位置,其中i表示位序,第i个元素的下标i-1,i的范围是1~n+1  
  4. //时间复杂度:O(n)  
  5. void insertSqList(SqList &L,int i, ElemType e){  
  6.     if(i>L.len+1||i<1){  
  7.         printf("插入位置参数不合法");  
  8.     }else if(L.len >= LIST_INIT_SIZE){  
  9.         printf("表已满,无法差插入");  
  10.     }else{  
  11.         int j = L.len-1;  
  12.         for(j;j>=i-1;j--){  
  13.             L.data[j+1] = L.data[j];//从后往前移动元素  
  14.         }  
  15.         L.data[i-1] = e;  
  16.         L.len++;  
  17.     }  
  18. }  
[cpp] view plain copy
  1. 演示:  
[cpp] view plain copy
  1. void main(){  
  2.       
  3.     //初始化一个空的线性表  
  4.     SqList L;  
  5.     L.len=0;  
  6.       
  7.     createSqList(L, 5);//创建一个线性表  
  8.     printSqList(L);  
  9.       
  10.     //完成插入功能  
  11.     printf("您要插入的数据和位置(1~%d)(如:在第2个位置插入10则输入:10,2):",L.len);  
  12.     int elem, pos;  
  13.     scanf("%d,%d",&elem,&pos);  
  14.     insertSqList(L,pos,elem);  
  15.     printSqList(L);  
  16. }  

[cpp] view plain copy

  1. //创建一个线性表实际上也是不断往一个空表里插入元素的过程  
  2. //所以可利用插入算法实现线性表的创建  
  3. void createUseInsertSqList(SqList &L, int n){  
  4.     printf("请输入%d个数:\n", n);  
  5.     int x;  
  6.     for(int i = 0; i < n; i++){  
  7.         scanf("%d", &x);  
  8.         insertSqList(L,i+1,x);  
  9.     }  
  10.     L.len = n;  
  11. }  

[cpp] view plain copy
  1. 演示:  

[cpp] view plain copy
  1. void main(){  
  2.       
  3.     //初始化一个空的线性表  
  4.     SqList L;  
  5.     L.len=0;  
  6.     /* 
  7.     createSqList(L, 5);//创建一个线性表 
  8.     printSqList(L); 
  9.     */  
  10.       
  11.     createUseInsertSqList(L, 5);  
  12.     printSqList(L);  
  13. }  


4.删除操作

[cpp] view plain copy
  1. //删除第i(1<=i<=L.len)个元素,并用e返回其值  
  2. //时间复杂度:O(n)  
  3. void delSqList(SqList &L, int i, ElemType &e){  
  4.     if(i>L.len||i<1){  
  5.         printf("删除位置参数不合法");  
  6.     }  
  7.     int j = i-1;//j是要被删除元素的下标  
  8.     e = L.data[j];  
[cpp] view plain copy
  1. printf("删除的第%d位置的数据是%d\n",i,e);  
  2. for(j;j<L.len-1;j++){  
  3.     L.data[j] = L.data[j+1];  
  4. }  
  5. L.len--;  
[cpp] view plain copy
  1. 演示:  
[cpp] view plain copy
  1. void main(){  
  2.       
  3.     //初始化一个空的线性表  
  4.     SqList L;  
  5.     L.len=0;  
  6.       
  7.     createSqList(L, 5);//创建一个线性表  
  8.     printSqList(L);  
  9.       
  10.     //完成删除功能  
  11.     printf("您要删除的数据的位置(如:要删除第2个位置的数据则输入(1~%d):2):",L.len);  
  12.     int pos;  
  13.     ElemType elem;  
  14.     scanf("%d",&pos);  
  15.     delSqList(L,pos,elem);  
  16.     printSqList(L);  
  17. }  


5.两个线性表的merge操作

[cpp] view plain copy
  1. //已知线性表La和Lb中的数据元素按值非递减排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍然按值非递减有序排列  
  2. //实现:为保持Lc的非递减有序,则当a<=b时,c=a;当a>b时,c=b  
  3. //时间复杂度:O(La.len+Lb.len)  
  4. //实例:La=(3,5,8,11),Lb=(2,6,8,9,11,15,20),Lc=(2,3,5,6,8,8,9,11,11,15,20),注意并没有去重,只是做了合并  
  5. void mergeSqList(SqList La, SqList Lb, SqList &Lc){  
  6.     int i=0, j=0;  
  7.     Lc.len=La.len+Lb.len;//初始化Lc  
  8.     int k =0;  
  9.     while(i<La.len&&j<Lb.len){  
  10.         if(La.data[i]<=Lb.data[j]){  
  11.             Lc.data[k]=La.data[i];  
  12.             i++;  
  13.             k++;  
  14.         }else{  
  15.             Lc.data[k]=Lb.data[j];  
  16.             j++;  
  17.             k++;  
  18.         }  
  19.     }  
  20.     while(i<La.len){  
  21.         Lc.data[k]=La.data[i];  
  22.         i++;  
  23.         k++;  
  24.     }  
  25.     while(j<Lb.len){  
  26.         Lc.data[k]=Lb.data[j];  
  27.         j++;  
  28.         k++;      
  29.     }  
  30. }  
[cpp] view plain copy
  1. 演示:  
[cpp] view plain copy
  1. void main(){  
  2.     //完成merge操作  
  3.     SqList La, Lb, Lc;  
  4.     //初始化线性表  
  5.     La.len = Lb.len =Lc.len = 0;  
  6.     printf("创建线性表La:\n");  
  7.     createSqList(La, 4);//创建线性表La  
  8.     printSqList(La);  
  9.     printf("创建线性表Lb:\n");  
  10.     createSqList(Lb, 7);//创建线性表Lc  
  11.     printSqList(Lb);  
  12.     mergeSqList(La, Lb, Lc);  
  13.     printf("merge以后得到的Lc:");  
  14.     printSqList(Lc);  
  15. }  


6.两个线性表的union操作

[cpp] view plain copy
  1. //利用两个线性表La,Lb分别表示两个集合A和B(线性表中的数据元素即为集合元素),现要求一个新的集合A=AUB  
  2. //实现:扩展线性表La,即从Lb中依次取得每个数据元素,并依值在La中进行查访,若在La中不存在则插入之。  
[cpp] view plain copy
  1. //实例:La=(3,5,8,11),Lb=(2,6,8,9,11,15,20),union以后的La=(3,5,8,11,2,6,9,15,20),La.len=9,注意有去重,但不care求并集以后的顺序  
  2. //时间复杂度:O(La.len * Lb.len)  
  3. int locateElem(SqList L, ElemType e){//查找线性表L中第一个与数据元素e相等(也可以是其他比较方法)的元素的位置(1~L.len),  
  4. //若没找到则返回0,找到则返回位序,时间复杂度:O(L.len)  
  5.     int i = 1;//i表示位序  
  6.     while(i<=L.len&&L.data[i-1]!=e){  
  7.         i++;  
  8.     }  
  9.     if(i<=L.len)  
  10.         return i;  
  11.     else  
  12.         return 0;  
  13. }  
  14. void unionSqList(SqList &La, SqList Lb){  
  15.     for(int i = 0; i < Lb.len; i++){  
  16.         ElemType e = Lb.data[i];  
  17.         if(!locateElem(La, e)){//e在La中不存在//O(La.len)  
  18.             insertSqList(La,La.len+1, e);//由于总在表尾插入,所以插入操作的时间复杂度与表长无关  
  19.         }  
  20.     }  
  21. }  
[cpp] view plain copy
  1. 演示:  
[cpp] view plain copy
  1. void main(){  
  2.     //完成union操作  
  3.     SqList La, Lb;  
  4.     //初始化线性表  
  5.     La.len = Lb.len = 0;  
  6.     printf("创建线性表La:\n");  
  7.     createSqList(La, 4);//创建线性表La  
  8.     printSqList(La);  
  9.     printf("创建线性表Lb:\n");  
  10.     createSqList(Lb, 7);//创建线性表Lc  
  11.     printSqList(Lb);  
  12.     unionSqList(La, Lb);  
  13.     printSqList(La);  
[cpp] view plain copy
  1. printf("La的长度为%d\n",La.len);  


注意:将merge第一个循环体中以switch语句代替if语句,即分出3种情况,当a=b时,只将两者之一插入到Lc中,则此时算法完成的操作和union完全相同,而时间复杂度却不同,其原因有二:

    1.La,Lb中的元素都是依值递增(同一集合中元素不等),则对Lb中每个元素,不需要再La中从表头至表尾进行全程搜索

    2.由于用新表Lc表示“并集”,则插入操作实际上借助“复制”完成,而无须因插入导致移动一系列元素
由此可见,若以线性表表示集合并进行集合的各种运算,应先对表中的元素进行排序,则可降低集合运算的时间复杂度