数据结构一——顺序表

顺序表基本运算的实现

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<algorithm>
  4 #define MaxSize 50
  5 using namespace std;
  6 
  7 typedef int ElemType;
  8 
  9 typedef struct
 10 {
 11     ElemType data[MaxSize];        //线性表中的元素
 12     int length;                    //线性表长度
 13 }SqList;
 14 
 15 //初始化线性表
 16 //只需分配线性表的存储空间,并将length设为0
 17 void InitList(SqList * &L)
 18 {
 19     L = (SqList *)malloc(sizeof(SqList));
 20     L->length = 0;
 21 }
 22 
 23 //由a中的n个元素建立顺序表
 24 void CreatList(SqList * &L, ElemType a[], int n)
 25 {
 26     int k = 0;
 27     L = (SqList *)malloc(sizeof(SqList));
 28     for (int i = 0; i < n; i++)
 29         L->data[i] = a[i];
 30     L->length = n;
 31 }
 32 
 33 //销毁线性表
 34 //就是释放线性表L占用的空间
 35 void DestroyList(SqList * &L)
 36 {
 37     free(L);
 38 }
 39 
 40 //判断线性表是否为空
 41 bool ListEmpty(SqList * L)
 42 {
 43     return L->length == 0;
 44 }
 45 
 46 //求线性表的长度
 47 //顺序表是O(1)
 48 int ListLength(SqList * L)
 49 {
 50     return L->length;
 51 }
 52 
 53 //输出线性表
 54 void DispList(SqList * L)
 55 {
 56     for (int i = 0; i < L->length; i++)
 57         printf("%d ", L->data[i]);
 58     printf("\n");
 59 }
 60 
 61 //求线性表中第i个元素值e
 62 bool GetElem(SqList * L, int i, ElemType &e)
 63 {
 64     if (i < 1 || i > L->length)  return false;            //参数i错误时放回false
 65     e = L->data[i];
 66     return true;
 67 }
 68 
 69 //按元素值查找
 70 //在顺序表中查找第一个值与e相等的元素的逻辑序号
 71 int LocateElem(SqList * L, ElemType e)
 72 {
 73     bool pos = 0;            //默认为0,表示没找到
 74     for (int i = 0; i < L->length; i++)
 75         if (L->data[i] == e)
 76         {
 77             pos = i + 1;
 78             break;
 79         }
 80     return pos;
 81 }
 82 
 83 //插入元素
 84 //在顺序表的第i个位置上插上新元素e
 85 bool ListInsert(SqList * &L, int i, ElemType e)
 86 {
 87     if (i < 1 || i > L->length + 1)  return false;    
 88     i--;
 89     for (int j = L->length; j > i; j--)  L->data[j] = L->data[j - 1];  //将data[i]及以后的元素后移一位
 90     L->data[i] = e;
 91     L->length++;
 92     return true;
 93 }
 94 
 95 //删除元素
 96 bool ListDelete(SqList * &L, int i, ElemType &e)
 97 {
 98     if (i < 1 || i > L->length) return false;
 99     i--;
100     e = L->data[i];
101     for (int j = i; j < L->length; j++) L->data[j] = L->data[j + 1];
102     L->length--;
103     return true;
104 }
105 
106 //一些应用
107 //1、删除顺序表中所有值等于x的元素,要求时间复杂度为O(n)、空间复杂度为O(1)
108 void Delnode1(SqList * &L, ElemType x)
109 {
110     int cnt = 0;    //记录不等于x的元素的个数,即要插入到L中的元素的个数
111     for(int i = 0;i < L->length;i++)
112         if (L->data[i] != x)
113             L->data[cnt++] = L->data[i];
114     L->length = cnt;
115 }
116 void Delnode2(SqList * &L, ElemType x)
117 {
118     int cnt = 0;    //记录等于x的元素的个数
119     for (int i = 0; i < L->length; i++)
120     {
121         if (L->data[i] == x)  cnt++;
122         else  L->data[i - cnt] = L->data[i];
123     }
124     L->length -= cnt;
125 }
126 
127 //2、尽可能设计一个高效的算法,使得以第一个元素为分界线,将所有小于等于它的元素移到该基准前面,大于它的元素移到该基准的后面
128 //以下两个都是时间复杂度为O(n)、空间复杂度为O(1)
129 void partition1(SqList * &L)
130 {
131     int i = 0, j = L->length - 1;
132     ElemType pivot = L->data[0];
133     while (i < j)
134     {
135         while (i < j && L->data[j] > pivot)  j--;    //先要得到j,可考虑3、1、7、5、4
136         while (i < j && L->data[i] <= pivot) i++;    //从左到右扫描,找到一个大于pivot的元素
137         if (i < j)  swap(L->data[i], L->data[j]);
138     }
139     swap(L->data[0], L->data[i]);            //最后将基准移到中间
140 }
141 void partition2(SqList * &L)
142 {
143     int i = 0, j = L->length - 1;
144     ElemType pivot = L->data[0];
145     while (i < j)
146     {
147         while (i < j && L->data[j] > pivot)  j--;
148         L->data[i] = L->data[j];            //利用第一位的空位
149         while (i < j && L->data[i] <= pivot)  i++;
150         L->data[j] = L->data[i];
151     }
152     L->data[i] = pivot;
153 }
154 
155 //3、设计一个尽可能高效的算法,将所有奇数移动到偶数的前面
156 //以下两个都是时间复杂度为O(n)、空间复杂度为O(1)
157 void move1(SqList * &L)
158 {
159     int i = 0, j = L->length - 1;
160     while (i < j)
161     {
162         while (i < j && L->data[j] % 2 == 0)  j--;        //从右向左扫描,找到一个奇数
163         while (i < j && L->data[i] % 2 == 1)  i++;        //从左向右扫描,找到一个偶数
164         if (i < j)  swap(L->data[i], L->data[j]);
165     }
166 }
167 void move2(SqList * &L)
168 {
169     int cnt = -1;        //当前奇数的个数
170     for(int i = 0;i <= L->length;i++)    
171         if (L->data[i] % 2 == 1)            //i指向奇数时
172         {
173             cnt++;
174             if (cnt != i)  swap(L->data[cnt], L->data[i]);
175         }
176 }

 参考资料:数据结构教程  李春葆版

猜你喜欢

转载自www.cnblogs.com/lfri/p/9943512.html