第二章线性表
线性表的特点:
(1)同一性,线性表由同类数据元素组成,每一个ai必须属于同一数据类型。
(2)有穷性,由有限个数据元素组成,表长度就是表中数据元素的个数
(3)有序性,线性表中相邻数据元素之间存在着序偶关系<ai,ai+1>
存放线性表的两种基本存储结构:顺序存储结构和链式存储结构
顺序表:表中元素的逻辑顺序与物理顺序相同,通常用数组来描述顺序表
注:线性表中元素的位序从1开始,数组中元素的下标是从0开始的。
静态分配:数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据就会产生溢出,进而导致程序崩溃。
#define MaxSize 50 typedef int ElemType; typedef struct { ElemType data[MaxSize];//顺序表的元素 int length;//顺序表的长度 }SqList;//顺序表的类型定义
动态分配:存储数组的空间是在程序执行过程中通过动态存储分配语句分配,一旦数据空间占满,就另外开辟一块更大的存储空间,用以替换原来的存储空间。
typedef struct { ElemType* data;//指示动态分配数组的指针 int Maxsize, length;//数组的最大容量和当前个数 }SeqList;
基本操作:
void IncreaseSize(SeqList* L, int len) { int *p = L->data; L->data = (ElemType*)malloc((L->Maxsize + len) * sizeof(ElemType)); for (int i = 0; i < L->length; i++) { L->data[i] = p[i]; } L->Maxsize = L->Maxsize + len; free(p); }
void InitList(SeqList* L) { L->data = (ElemType*)malloc(InitSize * sizeof(ElemType)); L->length = 0; L->Maxsize = InitSize; }
int ListInsert(SqList* L, int i, ElemType e) { if (i<1 || i>L->length + 1)//判断i是否有效,因为顺序表中数据元素存储是连续的,所以当i=length+2时无效,造成不连续 return false; if (L->length >= MaxSize)//存储空间已满,不能插入 return false; for (int j = L->length; j >= i; j--) L->data[j] = L->data[j - 1]; L->data[i - 1] = e; L->length++; return 1; } int ListDelete(SqList* L, int i, ElemType* e) { if (i<1 || i>L->length) return false; e = L->data[i - 1]; for (int j = i; j <= L->length; j++) L->data[j - 1] = L->data[j]; L->length--; return 1; }int LocateElem(SqList L, ElemType e) { int i; for (i = 0; i <L.length; i++) if (L.data[i] == e) return i + 1; return 0; } ElemType GetElem(SqList L, int i) { return L.data[i - 1]; }
//删最小 int DelMin(SeqList* L, ElemType* e) { if (L->length = 0) return 0; e=L->data[0]; int i; for (i = 1; i < L->length; i++) { if (e > L->data[i]) e = L->data[i]; } L->data[i] = L->data[L->length-1]; L->length--; return e; } //逆置 int Reverse(SeqList* L) { ElemType temp; int i; for (i = 0; i < L->length / 2; i++) { temp = L->data[i]; L->data[i] = L->data[L->length - i-1]; L->data[L->length - i - 1] = temp; } }
//删所有x顺序表,记录等于x的个数,改变顺序表长度 void DelX(SqList* L,ElemType x) { int count = 0;//记录值等于x的个数 int i=0; while (i < L->length) { if (L->data[i] == x) count++; else L->data[i - count] = L->data[i]; i++; } L->length = L->length - count; } // void Del2X(SqList* L, ElemType x) { int k = 0; for (int i = 0; i < L->length; i++) if (L->data[i] != x) { L->data[k] = L->data[i]; k++; } } //删值在s和t之间的数,有序顺序表 int DeLST(SqList* L, ElemType s, ElemType t) { int i, j; if (s >= t || L->length == 0) return false; for (i = 0; i < L->length && L->data[i] < s; i++);//找到大于等于s的第一个元素 if (i >= L->length) return false; for (j = i; j < L->length && L->data[j] <= t; j++); //找到大于t的第一个元素 for (; j < L->length; i++, j++)//前移,填补被删元素位置 L->data[i] = L->data[j]; L->length = i; return true; } //删值在s和t之间的数,顺序表 int DELST(SqList* L, ElemType s, ElemType t) { int i, k=0; if (s >= t || L->length == 0) return false; for (i = 0; i < L->length; i++) { if (L->data[i] >= s && L->data[i] <= t) k++; else L->data[i - k] = L->data[i]; } L->length = L->length - k; return true; } //删除有序表中相同元素保留一个 int DELSame(SqList* L) { if (L->length == 0) return false; int i,j; for (i = 0, j = 1; j < L->length; j++) if (L->data[i] != L->data[j])//查找下一个与上个元素值不同的元素 L->data[++i]=L->data[j];//找到后,将元素前移 L->length = i + 1; return true; } int Merge(SqList A, SqList B, SeqList* C) { if (A.length + B.length > C->Maxsize) return false; int i = 0, j = 0, k = 0; while (i < A.length && j< B.length) { if (A.data[i] <= B.data[j]) C->data[k++] = A.data[i++]; else C->data[k++] = B.data[j++]; } while (i < A.length) C->data[k++] = A.data[i++]; while (j < B.length) C->data[k++] = B.data[j++]; C->length = k; return true; }
//(a1,a2,...an,b1,b2,b3,...bn)转换成(b1,b2,...,bn,a1,a2,a3,...am)1.先将整个数组逆置,然后对bn....逆置,在对am...逆置 void reverse(ElemType A[], int left, int right, int arraySize) {//逆置 if (left >= right || right >= arraySize) return; int mid = (left + right) / 2; for (int i = 0; i < mid - left; i++) { ElemType temp = A[left + i]; A[left + i] = A[right - i]; A[right - i] = temp; } } void Exchange(ElemType A[], int m, int n, int arraysize) { Reverse(A, 0, m + n - 1, arraysize); Reverse(A, 0, n - 1, arraysize); Reverse(A, n, m + n - 1, arraysize); } void Binsearch(SqList* L, ElemType x) { int low = 0, high = L->length - 1; ElemType t; int mid,i; while (low<=high) { mid = (low + high) / 2; if (L->data[mid] == x) break; else if (L->data[mid] < x) { low = mid + 1; } else if (L->data[mid] > x) high = mid - 1; } if (L->data[mid] == x && mid != L->length - 1) {//若最后一个元素与mid处的元素相等,便不需要交换 t = L->data[mid]; L->data[mid] = L->data[L->length - 1]; L->data[L->length - 1] = t; } if (low > high) { for (i = L->length - 1; i > high; i--) L->data[i + 1] = L->data[i];//元素后移 L->data[i+1] = x; } }
//ab--->ba(逆置a,在逆置b,在逆置整个数组)时复杂度O(n),空复杂度O(1) void REverse(int R[], int from, int to) { int mid,temp,i; mid = (from + to) / 2; for (i = 0; i < mid - from; i++) { temp = R[from + i]; R[from + i] = R[to - i]; R[to - i] = temp; } } void Converse(int R[], int n, int p) { REverse(R, 0, p - 1); REverse(R, p, n - 1); REverse(R, 0, n - 1); } //分别求两个升序序列的中位数,1.若相等则输出 2若A[mid]<B[mid],舍弃A中较小部分,舍弃B较大部分,舍弃长度相同 //3.若A[mid]>B[mid],舍弃A中较大部分,舍弃B较小部分,舍弃长度相同 .重复123,直到两个序列中均只含一个元素为止,较小者为所求中位数 int M_Search(int A[], int B[], int n) { int s1 = 0, d1 = n - 1, m1, s2 = 0, d2 = n - 1, m2; while (s1 != d1 || s2 != d2) { m1 = (s1 + d1) / 2; m2 = (s2 + d2) / 2; if (A[m1] == B[m2]) return A[m1]; if (A[m1] < B[m2]) { if ((s1 + d1) % 2 == 0) {//元素个数为奇数 s1 = m1;//舍弃A中间点以前的部分且保留中间点 d2 = m2;//舍弃B中间点以后的部分且保留中间点 } else {//元素个数为偶数 s1 = m1 + 1;//舍弃A中间点以前的部分以及中间点 d2 = m2;//舍弃B中间点以后的部分且保留中间点 } } else { if ((s1 + d1)%2==0) { d1 = m1; s2 = m2; } else { d1 = m1; s2 = m2 + 1; } } } return A[m1] < B[m2] ? A[s1] : B[s2]; } int Majority(int A[], int n) { int i, c, count = 1; c = A[0]; for (i = 1; i < n; i++) if (A[i] == c) count++; else if (count > 0) count--; else { c = A[i]; count = 1; } if (count < 0) for (i = count = 0; i < n; i++) if (A[i] == c) count++; if (count > n / 2) return c; else return -1; } //找未出现的最小正整数 int FindMissMin(int A[], int n) { int i, *B; B = (int*)malloc(sizeof(int) * n);//分配空间 memset(B, 0, sizeof(int) * n);//赋初值为0 for (i = 0; i < n; i++) if (A[i] > 0 && A[i] <= n)//A[i]的值介于1-n,则标记数组B B[A[i] - 1] = 1; for (i = 0; i < n; i++)//扫描数组B,找到目标值 if (B[i] == 0) break; return i + 1;//返回结果 }
努力的意义就是放眼望去以后都是喜欢的人和事......

浙公网安备 33010602011771号