数据结构—线性表
线性表的定义
小节1 / 基本概念
是⼀一个有限序列列,表中各个元素是相继排列列的,且每两个相邻元素之间都有直接前驱和直接后
继的逻辑关系。
小节2 / 线性表的基本操作
这里可以写一个线性表的例子:
可以参考下这二个例子:
数据结构笔记:3.1 线性表的顺序存储结构:结构定义、初始化、查找、插入、删除某个元素、删除某个位置上的元素、创建顺序表:键盘输入数据、创建顺序表:随机赋值、打印顺序表、置空顺序表: link
数据结构:线性表的基本操作:link
一定要动手敲下
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define MAXSIZE 27/*存储空间初始分配量*/
#define OK 1
#define ERROR -1
typedef int ElemType;/*ElemType类型根据实际情况而定,这里假设为int*/
typedef struct
{/*线性表的顺序存储结构*/
ElemType data[MAXSIZE];/*数组存储数据元素*/
int length;/*线性表的当前长度*/
}SqList;
void MakeEmpty(SqList *S)
{/*初始化顺序表*/
S = (SqList *)malloc(sizeof(SqList));
S->length = 0;
}
int FindElement(SqList S, ElemType e)
{/*查询是否存在某个元素*/
int i = 0;
while (i < S.length&&S.data[i] != e)
i++;
if (i == S.length)/*如果不存在*/
return ERROR;
else/*如果存在返回位置*/
return i;
}
int ListInsert(SqList *S, int i, ElemType e)
{/*插入*/
int k;
if (i<1 || i>S->length + 1 || S->length == MAXSIZE)/*当插入的位置不在范围内和顺序表已满时*/
return ERROR;
if (i < S->length)
for (k = S->length; k >= i; k--)
S->data[k] = S->data[k - 1];
S->data[i] = e;
S->length++;
return OK;
}
int ListDeleteElseent(SqList *S, ElemType e)
{/*删除某个元素*/
int i = 0;
while(i < S->length&&S->data[i] != e)/*获取位置*/
i++;
if (i == S->length)/*如果被删除元素不存在*/
return ERROR;
while (i < S->length)
{/*将需要删除的元素后面的元素位置前移*/
S->data[i - 1] = S->data[i];
i++;
}
S->length--;
return OK;
}
int ListDeleteLocation(SqList *S, int i)
{/*删除某个位置上的元素*/
if (i<0 || i>S->length || S->length == 0)/*如果删除的位置不在范围内或顺序表为空*/
return ERROR;
while (i < S->length)
{/*将需要删除的元素后面的元素位置前移*/
S->data[i - 1] = S->data[i];
i++;
}
S->length--;
return OK;
}
void KeyboardInput(SqList *S)
{/*创建顺序表:键盘输入数据*/
int i, k, n;
printf("请输入需要键入的元素的个数:");
scanf_s("%d", &n);
S->length = n;
for (i = 1; i <= n; i++)
{
printf("请输入第%d个元素:", i);
scanf_s("%d", &k);
S->data[i - 1] = k;
}
}
void AutomaticAssignment(SqList *S)
{/*创建顺序表:随机赋值*/
int i, n;
printf("请输入需要键入的元素的个数:");
scanf_s("%d", &n);
S->length = n;
srand((unsigned)time(NULL));/*srand()函数为rand()函数提供变量*/
for (i = 1; i <= n; i++)
S->data[i - 1] = rand()%100+1;/*调用rand()产生的1至100个某个随机数*/
}
void display(SqList S)
{/*打印顺序表*/
int i;
if (S.length == 0)
printf("顺序表为空!\n");
else
{
printf("顺序表中数据为:");
for (i = 0; i < S.length; i++)
printf("%d ", S.data[i]);
putchar('\n');
}
}
void Supercilious(SqList *S)
{/*置空顺序表*/
S->length = 0;
}
void menu()
{/*菜单*/
printf("0:菜单\n1:初始化顺序表\n2:创建顺序表:键盘输入数据\n3:创建顺序表:随机赋值\n4:打印顺序表\n5:查询是否存在某个元素\n"
"6:插入\n7:删除某个元素\n8:删除某个位置上的元素\n9:置空顺序表\n10:退出程序\n");
}
int main(void)
{
int i = 0,j;
ElemType e;
SqList S;
MakeEmpty(&S);
while (i != 10)
{
switch (i)
{
case 0:menu(); break;
case 1:MakeEmpty(&S); break;
case 2:KeyboardInput(&S); break;
case 3:AutomaticAssignment(&S); break;
case 4:display(S); break;
case 5:
printf("请输入需要查找的元素:");
scanf_s("%d", &e);
FindElement(S, e);
break;
case 6:
printf("请输入需要插入的位置:");
scanf_s("%d", &j);
printf("请输入需要插入的元素:");
scanf_s("%d", &e);
ListInsert(&S, j, e);
break;
case 7:
printf("请输入需要删除的元素:");
scanf_s("%d", &e);
ListDeleteElseent(&S, e);
break;
case 8:
printf("请输入需要删除的元素的位置:");
scanf_s("%d", &j);
ListDeleteLocation(&S, j);
break;
case 9:Supercilious(&S); break;
default:printf("不存在该功能选项!\n");break;
}
printf("请输入需要执行的功能选项:");
scanf_s("%d", &i);
}
printf("感谢您的使用!\n");
return 0;
}
顺序表
小节1 / 顺序表的定义和特点
因为每个元素的性质相同,下面给出第i个元素的地址
顺序存储结构的结构体定义
这个定义比较常用,运用sqlist L 包含结构体属性的话
L.elem =L的元素部分 L.length=L的长度
L->elem L->length
小节2 / 顺序表主要操作的实现
查找
例子:在L线性表中查找值为e的序号
插入
例子:
i可以取值长度为 1~length+2
maxsize是线性表的最大空间
K往前移动
找到后,将e赋值给,最后记得加上长度加一
删除
跟插入差不多思路
最后记住长度-1
这里的程序不明白可以看这个笔记link
小节3 / 顺序表的应用举例
下面的是以指针为基础的链表结构,比较重要
单链表(线性表的链式存储)
单链表定义
单链表的结构定义
单链表主要操作
求长度
单链表的创建
二种方法,头插法和尾插法
头插入建表
尾插入建表
例子:
malloc——申请一个新节点
相当于这句申请了一个s的新节点,长度为sizeof(node),node的长度
新申请的s的地址赋给r的next
单链表的基本操作
查找
按序号找 i
在带头结点的单链表L中查找第1个结点
做一个初始的状态
判断条件。p的next节点不是空,并且还没数到第i个
按内容找 设内容key
没查完,不等于空
比较内容
找到后停止while循环,找到内容
插入
申请新节点
上面的是准备工作
删除
‘
找到这个要删除的元素的前一个结点后,它的结点的后一个是后一个的后一个,跳过要删除的结点r
把r结点里面的数据传送到e指针内,再free或者删除结点r
单链表的应用举例
两表相减
循环链表 和 双向链表
循环链表
双向链表
双向链表的每个数据结点都有两个指针,分别指向直接后继和直接前驱。
所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。