C语言 数据结构与算法 线性表
2016-03-23 00:00
465 查看
数据结构中逻辑结构分线性和非线性。
线性表即为线性结构中的一种。
线性表的特性百度百科解释在此。
个人总结为 有始有终,顺序排列,首尾不相连(像火车一样)。
线性表的基本操作如下:
初始化,销毁,重置为空表,判断是否为空,查找表的长度,
查找元素的位置,根据位置查找元素,查找元素的上一个元素,查找元素的下一个元素,
插入元素,删除元素,遍历元素。
下面是顺序存储结构的C实现。(有时间可以尝试下链式存储结构的实现)
看了几遍 终于通了,对新手来说其中比较难理解的地方就是插入元素 那个操作里的 位移操作 举例如下
list 里原本有 1 2 3 4 5 当需要插入 6 到 第二个位置 需要把 2 3 4 5 都往后移动 但是在上面的代码里移动的是元素地址 从最后一个开始 从高位往地位移动 所以比较难理解。
线性表即为线性结构中的一种。
线性表的特性百度百科解释在此。
个人总结为 有始有终,顺序排列,首尾不相连(像火车一样)。
线性表的基本操作如下:
初始化,销毁,重置为空表,判断是否为空,查找表的长度,
查找元素的位置,根据位置查找元素,查找元素的上一个元素,查找元素的下一个元素,
插入元素,删除元素,遍历元素。
下面是顺序存储结构的C实现。(有时间可以尝试下链式存储结构的实现)
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INIT_SIZE 10 //初始化表长度 #define INCREMENT_SIZE 5 //增量 typedef int Status; typedef int Elemtype; /* * 数据存贮结构 */ typedef struct { Elemtype *elem; //存储空间基址 int length; //当前长度 int size; //当前分配的表长大小 }SqList; /* * 初始化线性表 */ Status InitList(SqList *L) { L->elem = (Elemtype *) malloc(INIT_SIZE * sizeof(Elemtype)); if (!L->elem) { return ERROR; } L->length = 0; L->size = INIT_SIZE; return OK; } /* * 销毁 */ Status DestroyList(SqList *L) { free(L->elem); L->length = 0; L->size = 0; return OK; } /* * 清空 */ Status ClearList(SqList *L) { L->length = 0; return OK; } /* * 是否为空 */ Status isEmpty(const SqList L) { if (0 == L.length) { return TRUE; } else { return FALSE; } } /* * 获取表长 */ Status getLength(const SqList L) { return L.length; } /* * 获取指定位置的元素 */ Status GetElem(const SqList L, int i, Elemtype *e) { if (i < 1 || i > L.length) { return ERROR; } *e = L.elem[i-1]; return OK; } /* * 比较元素大小 */ Status compare(Elemtype e1, Elemtype e2) { if (e1 == e2) { return 0; } else if (e1 < e2) { return -1; } else { return 1; } } /* * 查找元素的位置 */ Status FindElem(const SqList L, Elemtype e, Status (*compare)(Elemtype, Elemtype)) { int i; for (i = 0; i < L.length; i++) { if (!(*compare)(L.elem[i], e)) { return i + 1; } } if (i >= L.length) { return ERROR; } } /* * 查找当前元素的前一个元素 */ Status PreElem(const SqList L, Elemtype cur_e, Elemtype *pre_e) { int i; for (i = 0; i < L.length; i++) { if (cur_e == L.elem[i]) { if (i != 0) { *pre_e = L.elem[i - 1]; } else { return ERROR; } } } if (i >= L.length) { return ERROR; } } /* * 查找当前元素的下一个元素 */ Status NextElem(const SqList L, Elemtype cur_e, Elemtype *next_e) { int i; for (i = 0; i < L.length; i++) { if (cur_e == L.elem[i]) { if (i < L.length - 1) { *next_e = L.elem[i + 1]; return OK; } else { return ERROR; } } } if (i >= L.length) { return ERROR; } } /* * 插入元素 */ Status InsertElem(SqList *L, int i, Elemtype e) { Elemtype *new; if (i < 1 || i > L->length + 1) { return ERROR; } if (L->length >= L->size) { new = (Elemtype*) realloc(L->elem, (L->size + INCREMENT_SIZE) * sizeof(Elemtype)); if (!new) { return ERROR; } L->elem = new; L->size += INCREMENT_SIZE; } Elemtype *p = &L->elem[i - 1]; Elemtype *q = &L->elem[L->length - 1]; for (; q >= p; q--) { *(q + 1) = *q; } *p = e; ++L->length; return OK; } /* * 删除元素 */ Status DeleteElem(SqList *L, int i, Elemtype *e) { if (i < 1 || i > L->length) { return ERROR; } Elemtype *p = &L->elem[i - 1]; *e = *p; for (; p < &L->elem[L->length]; p++) { *(p) = *(p + 1); } --L->length; return OK; } /* * 访问元素 */ void visit(Elemtype e) { printf("%d ", e); } /* * 遍历表 */ Status TraverseList(const SqList L, void (*visit)(Elemtype)) { int i; for(i = 0; i < L.length; i++) { visit(L.elem[i]); } return OK; } //测试 int main() { SqList L; if (InitList(&L)) { Elemtype e; printf("init_success\n"); int i; for (i=0; i<10; i++) { InsertElem(&L, i+1, i); } printf("length is %d\n", getLength(L)); if (GetElem(L, 1, &e)) { printf("This first element is %d\n", e); } else { printf("element id not exist\n"); } printf("The 5 at %d\n", FindElem(L, 5, *compare)); PreElem(L, 6, &e); printf("The 6's previoud element is %d\n",e); NextElem(L, 6, &e); printf("The 6's next element is %d\n", e); DeleteElem(&L, 1, &e); printf("delete first element is %d\n",e); TraverseList(L, visit); if (DestroyList(&L)) { printf("\ndestory_success"); } } }
看了几遍 终于通了,对新手来说其中比较难理解的地方就是插入元素 那个操作里的 位移操作 举例如下
list 里原本有 1 2 3 4 5 当需要插入 6 到 第二个位置 需要把 2 3 4 5 都往后移动 但是在上面的代码里移动的是元素地址 从最后一个开始 从高位往地位移动 所以比较难理解。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- C#数据结构之顺序表(SeqList)实例详解
- Lua和C语言的交互详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总