数据结构之线性表
线性表
线性表(Linear List)是n个数据元素的有限序列。
特点:
(1)唯一的首元素
(2)唯一的尾元素
(3)除首元素之外,每个元素都有唯一的前驱
(4)除尾元素之外,每个元素都有唯一的后继
线性表的顺序存储结构(用一组地址连续的存储单元依次存储元素):数组
线性表的链式存储结构(用一组地址任意的存储单元去存元素):链表
动态数组:(C实现)
//////////////// SqList.h ///////////////// 函数结果状态代码 ///////////// #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; ///////////////////////////////////////////////// #define LIST_INIT_SIZE 5 //线性表存储空间的初始分配增量 #define LISTINCREMENT 10 //线性表存储空间的分配增量 typedef int ElemType;//定义元素类型 typedef struct{ ElemType* elem; //存储空间基址 int length; //数组的当前长度 int listsize; //当前分配的存储容量(以size(ElemType)为单位) }SqList; //初始化 Status InitList_Sq(SqList* pL); //初始化2(指定分配的长度、容量) Status InitList2_Sq(SqList* pL, int length, int capacity); ///////////////////////////////////////////////////////////////////////////////// // 插入元素 // @parameter // pL 被操作的线性表list的地址 // i 插入元素的索引位置(base 0) // e 插入的元素 // @return // Status : OK、ERROR、INFEASIBLE、OVERFLOW ///////////////////////////////////////////////////////////////////////////////// Status ListInsert_Sq(SqList* pL, int i, ElemType e); ///////////////////////////////////////////////////////////////////////////////// // 删除元素 // @parameter // pL 被操作的线性表list的地址 // i 删除元素的索引 (base 0) // pE 返回被删除的元素 // @return // Status : OK、ERROR、INFEASIBLE、OVERFLOW ///////////////////////////////////////////////////////////////////////////////// Status ListDelete_Sq(SqList* pL, int i, ElemType* pE); //添加元素(在尾部) Status AddTail_Sq(SqList* pL, ElemType elem); //删除尾部元素 Status DeleteTail_Sq(SqList* pL, ElemType* pElem); ///////////////////////////////////////////////////////////////////////////////// // 定位元素(在list中查找第一个与e满足compare()的元素的索引) // @parameter // L 被查找的线性表 // e 定位的元素 // compare 函数指针 // @return // int : 成功,返回第一个与e满足compare()的元素的索引;失败,返回 -1 ///////////////////////////////////////////////////////////////////////////////// int LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType e1, ElemType e2)); // 查找元素(返回list中第一个元素e的索引) int FindElem_Sq(SqList L, ElemType e); ///////////////////////////////////////////////////////////////////////////////// // 合并顺序表(将两个有序的list合并为一个有序的list) // @parameter // La 有序list1 // Lb 有序list2 // pLc 返回合并后的list // @return // void ///////////////////////////////////////////////////////////////////////////////// void MergeList_Sq(SqList La, SqList Lb, SqList* pLc); // 打印List void DisplyList_Sq(SqList L); //------------------------------------------------------------------------------- //////////////// SqList.h #include "SqList.h" #include <stdio.h> #include <stdlib.h> //初始化 Status InitList_Sq(SqList* pL) { pL->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if (NULL == pL->elem)//内存分配失败 return OVERFLOW; pL->length = 0; pL->listsize = LIST_INIT_SIZE; return OK; } //初始化2(指定分配的长度、容量) Status InitList2_Sq(SqList* pL, int length, int capacity) { pL->elem = (ElemType*)malloc(capacity * sizeof(ElemType)); if (NULL == pL->elem)//内存分配失败 return OVERFLOW; pL->length = length; pL->listsize = capacity; return OK; } //添加元素(在尾部) Status AddTail_Sq(SqList* pL, ElemType elem) { return ListInsert_Sq(pL, pL->length, elem); } //删除尾部元素 Status DeleteTail_Sq(SqList* pL, ElemType* pElem) { return ListDelete_Sq(pL, pL->length, pElem); } ///////////////////////////////////////////////////////////////////////////////// // 插入元素 // @parameter // pL 被操作的线性表list的地址 // i 插入元素的索引位置(base 0) // e 插入的元素 // @return // Status : OK、ERROR、INFEASIBLE、OVERFLOW ///////////////////////////////////////////////////////////////////////////////// Status ListInsert_Sq(SqList* pL, int i, ElemType e) {//在元素L[i]之前插入元素e,i是数组下标 base 0 if (i < 0 || i > pL->length) return ERROR; if (pL->length >= pL->listsize) { ElemType* newbase = (ElemType*)realloc(pL->elem, (pL->listsize + LISTINCREMENT)*sizeof(ElemType)); if (NULL == newbase) return ERROR; pL->elem = newbase; pL->listsize += LISTINCREMENT; } ElemType* q = &(pL->elem[i]); //插入位置后的元素向后移动 for (ElemType* p = &(pL->elem[pL->length - 1]); p >= q; --q){ *(p + 1) = *p; } *q = e; ++pL->length; return OK; } ///////////////////////////////////////////////////////////////////////////////// // 删除元素 // @parameter // pL 被操作的线性表list的地址 // i 删除元素的索引 (base 0) // pE 返回被删除的元素 // @return // Status : OK、ERROR、INFEASIBLE、OVERFLOW ///////////////////////////////////////////////////////////////////////////////// Status ListDelete_Sq(SqList* pL, int i, ElemType* pE) { ElemType* p = NULL; ElemType* q = NULL; if (i < 0 || i > pL->length - 1) return ERROR; p = &(pL->elem[i]);//被删除元素的地址 if (NULL != pE) *pE = *p; //被删除元素之后的元素左移 q = pL->elem + pL->length; for (++p; p < q; ++p) { *(p - 1) = *p; } --pL->length; return OK; } ///////////////////////////////////////////////////////////////////////////////// // 定位元素(在list中查找第一个与e满足compare()的元素的索引) // @parameter // L 被查找的线性表 // e 定位的元素 // compare 函数指针 // @return // int : 成功,返回第一个与e满足compare()的元素的索引;失败,返回 -1 ///////////////////////////////////////////////////////////////////////////////// int LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType e1, ElemType e2)) { //int i = 1; //ElemType* p = pL->elem; //while (i < pL->length && (TRUE != compare(*p, e))) //{ // ++i; // ++p; //} //if (i < pL->length) // return i; //return -1; int i = 0; for (i = 0; i < L.length; ++i) { if (TRUE == compare(L.elem[i], e)) return i; } return -1; } // 比较函数 Status compare1(ElemType e1, ElemType e2) { if (e1 == e2) return TRUE; else return FALSE; } // 查找元素(返回list中第一个元素e的索引) int FindElem_Sq(SqList L, ElemType e) { return LocateElem_Sq(L, e, compare1); } ///////////////////////////////////////////////////////////////////////////////// // 合并顺序表(将两个有序的list合并为一个有序的list) // @parameter // La 有序list1 // Lb 有序list2 // pLc 返回合并后的list // @return // void ///////////////////////////////////////////////////////////////////////////////// void MergeList_Sq(SqList La, SqList Lb, SqList* pLc) { ElemType* pa = La.elem; ElemType* pb = Lb.elem; ElemType* pa_last = La.elem + La.length; ElemType* pb_last = Lb.elem + Lb.length; pLc->length = pLc->listsize = La.length + Lb.length; ElemType* pc = pLc->elem = (ElemType*)malloc(pLc->listsize * sizeof(ElemType)); if (NULL == pc) return ERROR;//分配内存失败 //归并 while (pa < pa_last && pb < pb_last) { if (*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while (pa < pa_last) *pc++ = *pa++; //插入La的剩余元素 while (pb < pb_last) *pc++ = *pb++; //插入Lb的剩余元素 } void DisplyList_Sq(SqList L) { SqList* pL = &L; printf("list:[elem=%#x,length=%d,listsize=%d]: ", pL->elem, pL->length, pL->listsize); for (int i = 0; i < pL->length; ++i) { printf("\t%d", *(pL->elem + i)); } printf("\n"); } //--------------------------------------------------- //测试 #include <stdio.h> #include "SqList.h" int main() { //printf("hello world.\n"); SqList list = { 0 }; InitList_Sq(&list); AddTail_Sq(&list, 10); AddTail_Sq(&list, 20); AddTail_Sq(&list, 30); AddTail_Sq(&list, 40); AddTail_Sq(&list, 50); ListInsert_Sq(&list, 5, 99); ElemType ele; ListDelete_Sq(&list, 3, NULL); DisplyList_Sq(list); //int pos = FindElem_Sq(list, 9); //printf("%d\n", pos); SqList list2 = { 0 }; //InitList2_Sq(&list2, 0, 3); AddTail_Sq(&list2, 11); AddTail_Sq(&list2, 21); AddTail_Sq(&list2, 60); DisplyList_Sq(list2); SqList list3; MergeList_Sq(list, list2, &list3); DisplyList_Sq(list3); }
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。