PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写好了,java还有三个特性,封装、继承、多态。当然这里不是讲Java,这里主要是说内部结构,大家都知道数据结构有些东西是分为逻辑结构和物理结构的,物理结构有分为顺序结构和链式结构,有不懂得可以百度百科,这里主要是分享线性表的顺序结构。那么什么是线性表呢,线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表
- 顺序表
- 链式表
1:顺序表分析
- 结构体创建
- 初始化顺序表
- 插入操作
- 删除操作
- 查找操作
- 修改操作
由于顺序表比较简单,这里解释都在代码中,在外就不在赘述。
1-1:结构体的创建
#define ElemType int #define MAXSIZE 100 //定义变量不需要分号。 //创建线性表 typedef struct { ElemType elem[MAXSIZE]; int length; //长度 } SqList;
1-2:初始化顺序表
int InitList(SqList &L) { // 初始化表,一个空表。 L.length = 0; return 0; }
1-3:操作方法
/** * @descibe 插入元素 * @param L 线性表 * @param pos 所在位置(并非角标) * @param data 插入元素 * */ int ListInsert(SqList &L, int pos, ElemType data) { if (pos < 1 || pos > L.length + 1) { printf("插入的不合法"); return -1; } int i; //在插入的同时,i要保证在pos以及pos后方,入1,2,3,4,5当在第3个插入时,须把原有的第三个数据以及以后数据后移一位,空出第三个位置。 for (i = L.length; i >= pos; i--) { L.elem[i] = L.elem[i - 1]; } L.elem[pos - 1] = data; L.length++; return 0;// } /** * 线性表中删除操作 * @param L 线性表 * @param pos 所在位置(并非角标) * @param data 插入元素 * */ int ListDelete(SqList &L, int pos, int data) { if (pos < 1 || pos > L.length) { printf("删除角标不合法"); return -1; } if (!(L.elem[pos - 1] == data)) { printf("没有这个数字"); return -1; } int i; //在插入的同时,i要保证在pos以及pos后方,入1,2,3,4,5当在第3个插入时,须把原有的第三个数据以及以后数据后移一位,空出第三个位置。 for (i = pos; i <= L.length; i++) { L.elem[i - 1] = L.elem[i]; } L.length--; return 0;//返回0表示成功; } //查找数据 int queryList(SqList L, int e) { //如果小于1证明没有数据,则直接返回。 if (L.length < 1) { printf("表中没有数据"); return -1; } for (int i = 0; i < L.length; i++) { if (L.elem[i] == e) { printf("找到该数据:%d角标为:%d \n", L.elem[i], i); } } return 0; } //修改数据 int xiugai(SqList &L, int pos, int e) { if (pos < 1 || pos > L.length) { printf("修改角标不合法"); return -1; } L.elem[pos - 1] = e; return 0; } //打印全部数据 void PrintF(SqList L) { printf("打印表中所有元素\n"); int i; for (i = 0; i < L.length; i++) { printf("%d\n", L.elem[i]); } }
综上所述:线性表和之前的数组类似,很容易理解。在使用的过程记得声明一下方法(函数);
2:链表分析
- 结构体创建
- 初始化顺序表
- 插入操作
- 删除操作
- 查找操作
- 修改操作
需要注意的是这里的结构体需要一个指针,前一个结点的指针指向下一个结点,依次类推,最后一个指针指向NULL;
2-1:结构体创建
/** * @describe 创建一个结构体 * SLink *next指针; * *SLinkListL 创建一个结构体指针 * */ typedef struct SLink { int data; struct SLink *next; } SLink, *SLinkListL;
2-2:初始化链表
/** * @describe 初始化链表 * */ SLinkListL initLinkL() { //1:分配一个空间 SLinkListL sLinkListL = (SLinkListL) malloc(sizeof(SLink)); //2:判断是否创建成功 if (!sLinkListL) { exit(-1); } sLinkListL->next = NULL; printf("初始化单链表成功\n"); return sLinkListL; }
2-3:操作--增删该查
这里需要注意的是修改这个操作,找p的时候要找到要修改的p,而不是前一个结点,比如说,咱们在第二个位置插入的时候要找到第一个位置作为p,二修改的时候就要找到第二个位置,也就是说pos传值的时候不用减一。
/** * @describe 插入操作 * * @param L 链表类型 * @param pos 插入位置 * @param e 插入元素 * */ int insertLinkL(SLinkListL &L, int pos, int e) { SLinkListL p = L; //判断是否符合链表的长度; int i = 0; //判断长度,寻找要插入的位置(前一位); while (p && i < pos-1) { p = p->next; i++; } //判断长度是否超过pos if (!p || i > pos-1) { return 0; } //为新元素创建结点(分配空间) SLinkListL s = (SLinkListL) malloc(sizeof(SLink)); s->data = e; s->next = p->next; p->next = s; return 1; } /** * @describe 删除操作 * @param L 链表类型 * @param pos 删除位置 * @param e 删除存放元素 * */ int deleteLinkL(SLinkListL &L, int pos, int *e) { SLinkListL p = L; //1:判断位置 int i = 0; while (p && i < pos-1) { p = p->next; i++; } if (!p || i > pos-1) { printf("删除位置不合法\n"); return -1; } //定义一个空的变量,用于存放p的指针,入a1,a2,a3,如果要删除a2,则p指向a1,此时,把a1的next先交给s(暂存,此时代表a2(因为a1的指针是指向a2)),然后用s去取下一个指针(next)就是a3, SLinkListL s;//s为了释放掉删除元素的空间 s = p->next; p->next = s->next; *e = s->data;//暂存 free(s); printf("删除成功\n"); return 0; } /** * @describe 查找操作 * @param L:链表类型 * @param e:e查找元素 * */ int queryLinkL(SLinkListL L, int e) { printf("查找元素为:%d",e); SLinkListL p = L; int i = 1; while (p) { p = p->next; if (p->data == e) { printf("找到元素%d\n", i); return 0; } i++; } printf("下标不合法/没有找到该数据"); return -1; } /** * @describe 修改操作 * @param L:链表类型 * @param i:修改元素的位置 * @param e:修改元素值 * */ int updataLinkL(SLinkListL &L, int pos, int e) { printf("修改数据为第:%d 个,值为:%d\n",pos,e); SLinkListL p = L; int i = 0; while (p && i < pos) { p = p->next; i++; } if (!p || i > pos) { printf("修改失败--原因:修改的下标越界\n"); return -1; } p->data = e; printf("修改成功\n"); return 0; } void printLL(SLinkListL L) { printf("打印全部数据\n"); SLinkListL p = L->next; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); }
综上所述:只多了一个指针,一开始看估计还有有看不懂的地方,按照顺序把代码粘贴到你编辑器上,运行起来慢慢看。
原文地址:https://www.cnblogs.com/cmusketeer/p/9740789.html
时间: 2024-10-24 20:00:58