线性表的定义
- 线性表就是零个或多个相同数据元素的有限序列
线性表特征(假设a为一张线性表)
- 对非空表,a[0]是表头,无前驱
- a[n-1]是表尾,无后继
- 其它的每个元素a[i]有且仅有一个直接前驱a[i-1]和一个后继a[a+1]
线性表的基本运算(假设L为一张线性表)
- 建立一个空表:Createlist(L)
- 置空表:ClearList(L)
- 判断表是否为空:IsEmpty(L)
- 若为空返回True(1),否则返回False(0)
- 求表长:Length(L)
- 取表中的某个元素:GetList(L,i),即L[i],要求 0<=i<legth(L)-1
- 定位运算:Locate(L,x) 确定元素x在表L的位置
- 如果存在返回位置信息,如果不存在返回-1
- 插入:Insert(L,x,i),将元素x插入到L表的第i个元素之前,且表长+1
- 添加:Add(L,x),将元素x加入到L表中,且长+1
- 删除:Delete(L,i),删除表L的第i个元素,且表长-1,要求 0<=i<legth(L)-1
- 复合元素
- 合并:Merge(L1,L2),将表L1和表L2合并为一张表,去重
- 去重:Deduplication(L),将表L的元素去重
顺序存储
- 顺序存储结构的特点
- 逻辑上相邻的额元素a[i],a[i+1],其存储位置也是相邻的
- 对数据元素a[i]的存取为随机存取或按地址存取
- 存储密度高。存储密度D=(数据结构中元素所占存储空间)/(整个数据结构所占空间)
- 顺序存储结构的不足
- 对表的插入和删除等运算时间复杂度较高
#include <stdio.h> #include <stdlib.h> // 线性表底层数组的长度 #define TableNum 6 // 线性表声明 typedef struct LinearTable { int List[TableNum]; // 数组长度 int last; // 尾端标志位 } L; // 初始化方法 L *initLinearTable() { L *LTable = NULL; if ((LTable = (L *) malloc(sizeof(L))) == NULL) { printf("Did not apply for enough memory space"); return NULL; } LTable->last = -1; return LTable; }; // 展现所有内容: void Show(L *LTable) { printf("========start========= "); for (int i = 0; i < LTable->last + 1; ++i) { printf("index:%d -> value:%d ", i, *(LTable->List + i)); } printf("========end========= "); } // 置空表 void ClearList(L *LTable) { LTable->last = -1; }; // 判断是否为空 int IsEmpty(L *LTable) { if (LTable->last == -1) { return 1; } return 0; }; // 求数组长度 int Length(L *LTable) { return LTable->last + 1; }; // 获取表中某个位置的元素 int GetElement(L *LTable, int i) { // 判断i的有效性 否则返回-1 if (i >= 0 && i <= LTable->last) { return *(LTable->List + i); } return -1; }; // 寻找表是否存在某元素 int LSearch(L *LTable, int element) { for (int i = 0; i <= LTable->last; ++i) { if (*(LTable->List + i) == element) { return i; } } return -1; }; // 插入 void LInsert(L *LTable, int index, int element) { // 在数组有效范围内 index也在可取范围内 if (index >= 0 && index <= TableNum - 1 && index - 1 <= LTable->last && LTable->last < TableNum - 1) { LTable->last++; for (int i = LTable->last; i > index; --i) { *(LTable->List + i) = *(LTable->List + i - 1); } *(LTable->List + index) = element; } else { printf("insert error list index:%d insert index:%d ", LTable->last, index); } }; // 加入 void Add(L *LTable, int element) { // 在数组有效范围内 if (LTable->last < TableNum - 1) { LTable->last++; *(LTable->List + LTable->last) = element; } else { printf("Add Error length > %d", TableNum); } } // 删除 void LDelete(L *LTable, int index) { if (index >= 0 && index <= LTable->last) { LTable->last--; for (int i = index; i <= LTable->last; ++i) { *(LTable->List + i) = *(LTable->List + i + 1); } } else { printf("Delete error: index:%d last:%d ", index, LTable->last); } }; // 清除该数据结构 void Del(L *LTable) { free(LTable); } int main(int argc, const char *argv[]) { printf("======test======= "); L *now; int i; // 新建 now = initLinearTable(); // 判断是否为空 i = IsEmpty(now); printf("是否为空: %d ", i); // 判断长度 i = Length(now); printf("长度为: %d ", i); // 添加数据 Add(now, 1); Add(now, 2); // 展示所有 Show(now); // 判断是否为空 i = IsEmpty(now); printf("是否为空: %d ", i); // 判断长度 i = Length(now); printf("长度为: %d ", i); // 插入 LInsert(now, 0, 3); // show Show(now); LInsert(now, 3, 4); // show Show(now); // delete LDelete(now, 3); // show Show(now); // // 清空 // ClearList(now); // // show // Show(now); // 按位置获取元素 // 释放 free(now); now = NULL; // 后面报错 i = GetElement(now, 2); printf("元素为: %d ", i); // 查找是否有元素 i = LSearch(now, 5); printf("索引为: %d ", i); i = Length(now); printf("长度为: %d ", i); }
链式存储
#include <stdio.h> #include <stdlib.h> // 链表结构 typedef struct LinkList { int data; struct LinkList *next; } LS; // 初始化 返回哑结点 LS *initLinkList() { LS *head = NULL; if ((head = (LS *) malloc(sizeof(LS))) == NULL) { printf("Did not apply for enough memory space "); return NULL; } head->next == NULL; return head; } // 封装函数 增加单链 LS *newLinkList(int i) { LS *head = NULL; if ((head = (LS *) malloc(sizeof(LS))) == NULL) { printf("Did not apply for enough memory space "); return NULL; } head->data = i; head->next == NULL; return head; } // show 展示函数 void Show(LS *link) { printf("========start========= "); link = link->next; while (link != NULL) { printf("%d ", link->data); link = link->next; } printf("========end========= "); } // 头部插入 void HeadAdd(LS *link, int i) { LS *member = NULL; LS *mid = NULL; member = newLinkList(i); if (member == NULL) { puts("Head Add error: No apply memory "); return; } mid = link->next; link->next = member; member->next = mid; } // 尾部插入 void TailAdd(LS *link, int i) { if (link == NULL) { puts("link is empty"); return; } LS *member = NULL; member = newLinkList(i); if (member == NULL) { puts("Head Add error: No apply memory "); return; } while (link->next != NULL) { link = link->next; } link->next = member; } // 指定插入 index 起止为0 void AssignAdd(LS *link, int index, int i) { if (index < 0) { printf("index:%d < 0 ", index); return; } // 特殊处理 插在首尾 if (index == 0) { LS *mid = NULL; LS *member = NULL; member = newLinkList(i); if (member == NULL) { puts("AssignAdd error: No apply memory "); return; } mid = link->next; link->next = member; member->next = mid; return; } while (link != NULL && index > 0) { index--; link = link->next; } if (link != NULL) { LS *mid = NULL; LS *member = NULL; member = newLinkList(i); if (member == NULL) { puts("AssignAdd error: No apply memory "); return; } mid = link->next; link->next = member; member->next = mid; return; } else { puts("index over link length "); } } // 指定删除 index 起止为0 void DeleteIndex(LS *link, int index) { if (index < 0) { printf("index:%d<0 ", index); return; } while (link != NULL && --index >= 0) { link = link->next; } if (link && link->next) { if (link->next && link->next->next) { link->next = link->next->next; } else { link->next = NULL; } } else { printf("index over length "); } } // 指定删除 data void DeleteData(LS *link, int data) { LS *Previous; Previous = link; link = link->next; while (link) { if (link->data == data) { Previous->next = link->next; return; } Previous = Previous->next; link = link->next; } printf("data is exist "); } // 寻找 根据index寻找 int SearchIndex(LS *link, int index) { if (index < 0) { printf("index:%d<0 ", index); return -1; } while (link != NULL && index != -1) { link = link->next; index--; } if (link != NULL) { return link->data; } return -1; } // 寻找 根据value寻找 int SearchData(LS *link, int data) { int i = 0; link = link->next; while (link != NULL) { if (link->data == data) { return i; } link = link->next; i++; } return -1; } // 排序 void sortLink(LS *link) { LS *other, *nowOther, *head; other = link->next; link->next = NULL; while (other) { nowOther = other; other = other->next; head = link; while (head->next && head->next->data < nowOther->data) { head = head->next; } nowOther->next = head->next; head->next = nowOther; } } // 释放 void Del(LS *link) { while (link != NULL) { free(link); link = link->next; } } int main() { // 初始化 LS *head = NULL; int i = 0; // 初始化 head = initLinkList(); Show(head); // 尾插 TailAdd(head, 3); TailAdd(head, 4); // 头插 HeadAdd(head, 1); HeadAdd(head, 2); TailAdd(head, 5); TailAdd(head, 6); Show(head); // 指定插入 AssignAdd(head, 3, 7); Show(head); // 寻找 i = SearchIndex(head, 6); printf("index:%d ", i); // 通过元素寻找 i = SearchData(head, 9); printf("index:%d ", i); // 排序 sortLink(head); Show(head); DeleteIndex(head, 6); Show(head); // 指定data删除 DeleteData(head,2); Show(head); Del(head); }
栈
栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为"栈顶",另一固定端称为"栈底",当栈中没有元素时称为"空栈"。特点,后进先出
基本运算
- 创建空栈
- 清空栈
- 判断栈是否为空
- 判断栈是否为慢
- 元素进栈
- 元素出栈
- 获取栈顶
#include <stdio.h> #include <stdlib.h> typedef struct stack { int *stackList; // 指向栈的数组 int stackLen; // 栈的长度 int top; // 目前头的位置 } stacks; // 初始化空栈 stacks *initStack(int stackLen) { if (stackLen <= 0) { puts("stackLen <= 0"); return NULL; } stacks *newStack = NULL; int *list; // 第一次申请内存 if ((newStack = (stacks *) (malloc(sizeof(stacks)))) == NULL) { puts("No memory at newStack"); return NULL; } if ((list = (int *) (malloc(sizeof(int[stackLen - 1])))) == NULL) { // 释放第一次申请的内存 free(newStack); puts("No memory at list"); return NULL; } newStack->top = -1; newStack->stackLen = stackLen; newStack->stackList = list; return newStack; } // show void show(stacks *stack) { printf("========start========= "); for (int i = 0; i <= stack->top; ++i) { printf("%d ", *(stack->stackList + i)); } printf("========end========= "); } // 判断是否为空栈 int isStackEmpty(stacks *stack) { if (!stack) { puts("stack no find"); return -1; } if (stack->top == -1) { return 1; } return 0; } // 判断是否为满栈 int isStackFull(stacks *stack) { if (!stack) { puts("stack no find"); return -1; } if (stack->top == stack->stackLen - 1) { return 1; } return 0; } // 入栈 void addStack(stacks *stack, int num) { int i = 0; // 先判断是否栈满 i = isStackFull(stack); if (i == 1 || i == -1) { // 满或者为空 puts("stack is full or no find"); return; } *(stack->stackList + (++stack->top)) = num; } // 出栈 int outStack(stacks *stack) { int i = 0; // 判断是否为空 i = isStackEmpty(stack); if (i == 1 || i == -1) { // 满或者为空 puts("stack is empty or no find"); return -1; } return *(stack->stackList + (stack->top--)); } // 查看栈顶 int topStack(stacks *stack) { int i = 0; i = isStackEmpty(stack); if (i == 1 || i == -1) { // 满或者为空 puts("stack is empty or no find"); return -1; } return *(stack->stackList + (stack->top)); } // 销毁 void Del(stacks *stack) { free(stack->stackList); stack->stackList = NULL; free(stack); } int main() { int i = 0; // 创建 stacks *stack = NULL; stack = initStack(5); show(stack); addStack(stack, 5); addStack(stack, 3); addStack(stack, 9); i = topStack(stack); printf("顶 %d ", i); addStack(stack, 4); show(stack); i = outStack(stack); printf("出栈 %d ", i); i = outStack(stack); printf("出栈 %d ", i); show(stack); // 查看顶 i = topStack(stack); printf("顶 %d ", i); show(stack); Del(stack); }
对列
特殊的线性表,先进先出(FIFO)
基本运算
- 创建空对列
- 清空对列
- 判断对列是否为空
- 判断对列是否为慢
- 元素进对列
- 元素出对列
#include <stdio.h> #include <stdlib.h> typedef struct alignment { int *alignmentList; // 指向对列的数组 int alignmentLen; // 栈的长度 int top; // 目前头的位置 int tail; // 指向尾的位置 } alignments; // 初始化方法 alignments *initAlignment(int alignmentLen) { if (alignmentLen <= 0) { puts("alignmentLen <= 0"); return NULL; } alignments *newAlignment = NULL; int *list = NULL; // 第一次申请内存 if ((newAlignment = (alignments *) malloc(sizeof(alignments))) == NULL) { puts("No memory at newAlignment"); return NULL; } // 第二次申请内存 if ((list = (int *) malloc(sizeof(int[alignmentLen]))) == NULL) { // 释放第一次申请的内存 free(newAlignment); puts("No memory at list"); return NULL; } newAlignment->alignmentLen = alignmentLen; newAlignment->alignmentList = list; newAlignment->top = 0; newAlignment->tail = alignmentLen - 1; return newAlignment; } // show void show(alignments *alignment) { int top, tail; top = alignment->top; tail = alignment->tail; printf("========start========= "); while ((tail + 1) % alignment->alignmentLen != top) { tail = (tail + 1) % alignment->alignmentLen; printf("%d ", *(alignment->alignmentList + tail)); } printf("========end========= "); } // 判断是否为空列 int isStackEmpty(alignments *alignment) { if (!alignment) { puts("alignment no find"); return -1; } if ((alignment->tail + 1) % alignment->alignmentLen == alignment->top) { return 1; } return 0; } // 判断是否为满列 int isStackFull(alignments *alignment) { if (!alignment) { puts("alignment no find"); return -1; } if (alignment->top == alignment->tail) { return 1; } return 0; } // 入列 void addAlignment(alignments *alignment, int num) { int i = 0; // 先判断是否栈满 i = isStackFull(alignment); if (i == 1 || i == -1) { // 满或者为空 puts("alignment is full or no find"); return; } *(alignment->alignmentList + alignment->top) = num; alignment->top = (++alignment->top) % alignment->alignmentLen; } // 出列 int outAlignment(alignments *alignment) { int i = 0; // 判断是否为空 i = isStackEmpty(alignment); if (i == 1 || i == -1) { // 满或者为空 puts("alignment is empty or no find"); return -1; } alignment->tail = (alignment->tail + 1) % alignment->alignmentLen; return *(alignment->alignmentList + alignment->tail); } // 销毁 void Del(alignments *alignment) { free(alignment->alignmentList); alignment->alignmentList = NULL; free(alignment); } int main() { int i = 0; // 创建 alignments *alignment = NULL; alignment = initAlignment(5); show(alignment); i = isStackEmpty(alignment); printf("是否为空:%d ", i); i = isStackFull(alignment); printf("是否为满:%d ", i); // 加入 addAlignment(alignment, 5); addAlignment(alignment, 3); addAlignment(alignment, 6); addAlignment(alignment, 9); addAlignment(alignment, 7); i = isStackEmpty(alignment); printf("是否为空:%d ", i); i = isStackFull(alignment); printf("是否为满:%d ", i); show(alignment); i = outAlignment(alignment); printf("出列:%d ", i); addAlignment(alignment, 1); addAlignment(alignment, 2); show(alignment); i = isStackEmpty(alignment); printf("是否为空:%d ", i); i = isStackFull(alignment); printf("是否为满:%d ", i); i = outAlignment(alignment); printf("出列:%d ", i); i = outAlignment(alignment); printf("出列:%d ", i); i = outAlignment(alignment); printf("出列:%d ", i); i = outAlignment(alignment); printf("出列:%d ", i); i = outAlignment(alignment); printf("出列:%d ", i); i = isStackEmpty(alignment); printf("是否为空:%d ", i); i = isStackFull(alignment); printf("是否为满:%d ", i); show(alignment); // 销毁 Del(alignment); }