顺序表 - 数据结构

  顺序表:用一组地址连续的存储单元依次存储线性表的数据元素。

  假设线性表的每个元素需占用d个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储位置。

  

  特点:

1)只要确定了存储顺序表的起始位置,顺序表中任一数据元素都可随机存取。

2)为表中相邻的元素赋以相邻的存储位置。

  缺点:在作插入或删除操作时,需移动大量元素。 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define ERROR            0
  5 #define OK                1
  6 #define OVERFLOW        -1
  7 #define LIST_INIT_SIZE    100        //顺序表存储空间的初始分配量
  8 #define LISTINCREMENT    10        //顺序表存储空间的分配增量
  9 typedef int ElemType;
 10 typedef int Status;
 11 typedef struct {
 12     ElemType *elem;                //存储空间基址
 13     int length;                    //当前长度
 14     int listsize;                //当前分配的存储容量
 15 } SqList;
 16 
 17 Status InitList_Sq(SqList &L) {
 18     // 构造一个空的顺序表L
 19     L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
 20     if (! L.elem)    exit(OVERFLOW);
 21     L.length = 0;
 22     L.listsize = LIST_INIT_SIZE;
 23     return OK;
 24 }    // InitList_Sq
 25 
 26 // 当在顺序表中某个位置插入或删除一个元素时,时间主要耗费在移动元素上
 27 Status ListInsert_Sq(SqList &L, int i, ElemType e) {
 28     // 在顺序表L中第i个位置之前插入新的元素e
 29     // i的合法值为 1<= i <= ListLength_Sq(L)+1
 30     if (i < 1 || i > L.length + 1) return ERROR;    // i值不合法
 31     if (L.length >= L.listsize) {        // 当前存储空间已满,增加分配
 32         ElemType *newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
 33         if (! newbase) exit(OVERFLOW);    // 存储分配失败
 34         L.elem = newbase;                // 新基址
 35         L.listsize += LISTINCREMENT;    // 增加存储容量
 36     }
 37     ElemType *q = &(L.elem[i-1]);
 38     for (ElemType *p = &(L.elem[L.length-1]); p >= q; --p) //插入位置及之后元素右移
 39         *(p+1) = *p;
 40     *q = e;        // 插入e
 41     ++L.length;    // 表长增1
 42     return OK;
 43 }    // ListInsert_Sq,时间复杂度为O(n)
 44 
 45 Status ListDelete_Sq(SqList &L, int i, ElemType &e) {
 46     // 在顺序表L中删除第i个元素,并用e返回其值
 47     // i的合法值为 i<= i <= ListLength_Sq(L)
 48     if (i < 1 || i > L.length) return ERROR;    // i值不合法
 49     ElemType *p = &(L.elem[i-1]);        // p为被删除元素的位置
 50     e = *p;
 51     ElemType *q = &(L.elem[L.length-1]);    //表尾元素位置
 52     for (++p; p <= q; ++p)    //被删除元素之后的元素左移
 53         *(p-1) = *p;
 54     --L.length;                // 表长减1
 55     return OK;
 56 }    // ListDelete_Sq,时间复杂度为O(n)
 57 
 58 int LocateElem_Sq(SqList &L, ElemType e) {
 59     // 在顺序表中查找第一个值与e相等的元素的位序
 60     // 若找到,则返回其在L中的位序,否则返回0
 61     int i = 1;            // i的初值为第1个元素的位徐
 62     ElemType *p = L.elem;        //第1个元素的存储位置
 63     while (i <= L.length && (*(p+i-1) != e))
 64         ++i;
 65     if (i <= L.length) return i;
 66     else return 0;
 67 }    // LocateElem_Sq,时间复杂度为O(n)
 68 
 69 void Union(SqList &La, SqList &Lb) {
 70     // 将所有在顺序表Lb中但不在La中的数据元素插入到La中
 71     int La_len = La.length;        //求顺序表的长度
 72     int Lb_len = Lb.length;
 73     for (int i = 1; i <= Lb_len; ++i) {
 74         ElemType e = Lb.elem[i-1];    // 取Lb中第i个数据元素赋给e
 75         // La中不存在和e相同的元素,则插入La
 76         if (!LocateElem_Sq(La, e)) ListInsert_Sq(La, ++La_len, e);
 77     }
 78 }    // Union
 79 
 80 void MergeList_Sq(SqList &La, SqList &Lb, SqList &Lc) {
 81     // 归并La和Lb得到新的顺序表Lc
 82     ElemType *pa = La.elem;
 83     ElemType *pb = Lb.elem;
 84     Lc.listsize = Lc.length = La.length + Lb.length;
 85     ElemType *pc = Lc.elem = (ElemType *)malloc(Lc.listsize * sizeof(ElemType));
 86     if (!Lc.elem) exit(OVERFLOW);
 87     ElemType *pa_last = La.elem + La.length - 1;
 88     ElemType *pb_last = Lb.elem + Lb.length - 1;
 89     while (pa <= pa_last && pb <= pb_last) {    // 归并
 90         if (*pa <= *pb) *pc++ = *pa++;
 91         else *pc++ = *pb++;
 92     }
 93     while (pa <= pa_last) *pc++ = *pa++;    // 插入La的剩余元素
 94     while (pb <= pb_last) *pc++ = *pb++;    // 插入Lb的剩余元素
 95 }    // MergeList_Sq
 96 
 97 Status Print_Sq(SqList &L) {
 98     for (int i = 0; i < L.length; ++i) {
 99         printf("%d ", L.elem[i]);
100     }
101     putchar('\n');
102     return OK;
103 }
104 
105 int main () {
106     SqList La;
107     InitList_Sq(La);
108     ListInsert_Sq(La, 1, 3);
109     ListInsert_Sq(La, 2, 5);
110     ListInsert_Sq(La, 3, 7);
111     ListInsert_Sq(La, 4, 8);
112     ListInsert_Sq(La, 5, 11);
113     printf("La is: ");
114     Print_Sq(La);
115 
116     SqList Lb;
117     InitList_Sq(Lb);
118     ListInsert_Sq(Lb, 1, 2);
119     ListInsert_Sq(Lb, 2, 3);
120     ListInsert_Sq(Lb, 3, 5);
121     ListInsert_Sq(Lb, 4, 6);
122     ListInsert_Sq(Lb, 5, 8);
123     ListInsert_Sq(Lb, 6, 8);
124     ListInsert_Sq(Lb, 7, 9);
125     ListInsert_Sq(Lb, 8, 11);
126     ListInsert_Sq(Lb, 9, 11);
127     ListInsert_Sq(Lb, 10, 15);
128     ListInsert_Sq(Lb, 11, 20);
129     printf("Lb is: ");
130     Print_Sq(Lb);
131 
132     ElemType e;
133     ListDelete_Sq(La, 3, e);
134     printf("New La: ");
135     Print_Sq(La);
136     printf("The deleted element is: %d\n", e);
137 
138     int index = LocateElem_Sq(La, 8);
139     printf("find the same element in La's position is %d\n", index);
140 
141     Union(La, Lb);
142     printf("Unioned La is: ");
143     Print_Sq(La);
144 
145     SqList Lc;
146     // InitList_Sq(Lc);
147     MergeList_Sq(La, Lb, Lc);
148     printf("Merge La and Lb, getting Lc: ");
149     Print_Sq(Lc);
150     return 0;
151 }

输出为:

La is: 3 5 7 8 11
Lb is: 2 3 5 6 8 8 9 11 11 15 20
New La: 3 5 8 11
The deleted element is: 7
find the same element in La's position is 3
Unioned La is: 3 5 8 11 2 6 9 15 20
Merge La and Lb, getting Lc: 2 3 3 5 5 6 8 8 8 9 11 2 6 9 11 11 15 15 20 20

 

posted @ 2015-10-15 14:54  pestle  阅读(496)  评论(0编辑  收藏  举报