数据结构和算法-线性表

数据结构

  1. 基础知识
    概念:数据组织的不同方式 以及 运算步骤 提高效率和空间利用情况
    复杂度:运算次数
    常用算法的复杂度分析:等学了算法来分析
    逻辑结构(抽象数据类型 比如线性表 树 图)和储存结构
  2. 表ADT
    顺序储存:数组,在存储空间上 连续整块的空间 需要判别满不满
    链式储存:数据分散在物理空间中 然后通过一条线保存逻辑关系 需要判别空不空
    线性表:就是一对一的数据关系。是数据结构中的逻辑结构
//线性表的定义:具有相同特性数据元素的有限序列(1:1的)
typedef struct LNode *List;// *List 是新类型struct Lnode的别名,指针类型的
struct LNode{ // 新类型中的元素
		ElementType Data[MAXSIZE];
		int Last;//  长度-1
}; //上一步定义结构体 
// 后面两个利用结构体定义两个变量 
Struct LNode L;//定义结构体类型变量
List PtrL;//定义结构体指针变量 

A:数组实现线性表的: 顺序表 初始化

// 数组的初始化
List Make Empty(){// 初始化的结构
List PtrL;
PtrL = (List)malloc(sizeof(struct LNode));
PtrL -> Last = -1;// -> 在c中用于只想结构体子数据的指针没有元素
return PtrL;// PtrL 是这个结构体的别名
}
//顺序表的查找
int Find(element type X,List PtrL){
int i =0;
while (i <= PtrL->Last && Ptrl->Data[i]!=X)
	i++;// 没有到最后一个 并且元素没匹配就是 +1找下一个
 if(i>PTrl->Last) return -1; //这种情况就是没有找到
 else return i;
}
//顺序表的插入 第i个位置 
// 1:移动 从后面开始挪
void insert(element type x,int i, List PtrL){
int j;
if(PtrL -> Last == MAXSIZE-1){
	printf("表满")return}
if(i<1 || i > PtrL -> Last +2){ // 因为线性表连续的定义 而且last是从0开始数的
printf("位置不合法")return}
// 通过一个for循环把 i-1后面的往后面移
for(j = PtrL -> Last;J>= i-1;j--) // 数组从0开始 所以第i个位置插入 得从i-1开始挪
	PtrL -> Data[j+1] = PtrL->Data[j];
PtrL ->Data[i-1] = X;
Ptrl -> Last++
return;
}
//顺序表的删除操作
void delete(int i ,List PtrL){
If(PtrL -> Last == -1){
printf("表空")return}
if(i < 1 || i > PtrL -> Last + 1){
printf("位置不合法")return}
for(j = i;j > PtrL->Last;j++){// for 循环的时候 等于 也要考虑进去
 PtrL -> Data[j-1] = PtrL -> Data[j];
 }
PtrL -> Last--;
}

链表:通过指针实现的不连续储存 不要求物理空间相邻
常用的操作:数据对象的长度测量,元素的增加/删减,找特定位置的元素

//定义
typedef Struct Lnode *List;
struct Lnode{//每个节点都是一个结构
 	ElementType Data;//
 	List Next;// 这里的话就是一个区域一个结构体是吗 因为内存结构是分散的
 }struct Lnode L;
 List PtrL;
int Length(List PtrL){
 List p = PtrL;//第一个的指针到最后一个指针 直到指到null;临时指针list 结构体类型的指针
 int J = 0;
 while(p){
 	p = p->Next;
 	j++
	}
	return j;
 }//O(n)
// 查找
List FindKth(int K, List PtrL){
List p = PtrL;
int i = 1;
while(!p = NULL && i <k){
 p = p->NEXT;//必须要一个一个遍历到
 i++;//退出循环有两种可能。一种不够长 一种找到了
 }
 if(i == K)
 return p;
 else return NULL;
}
//按值查找
List Find(element type X, List PtrL){
List p = PtrL;//临时指针;
while(p-> Data != X && p!=NULL)
	p=p->Next;//遍历的体现
return p
}
// 插入
List insert(element type X,int i, List PtrL){
// 只要修改两个指针的情况
list p ,s;
if(i == 1){
s = (List)malloc(sizeof(struct LNode));//分配一块新的内存空间。
s -> Data = X;//赋值
s -> Next = PtrL;//直接指向一开始的
return s;
}
p = FindKth(i-1,PtrL);//找到第i-1个的指针
if(p == NULL){
printf("参数错")return NULL}else{
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = P->Next;//原来的指向给到现在新的
p->Next = s;//重新指 这两部有顺序要求
return Ptrl;
}

}
// 删除
List delete(int i, List PtrL){
// 
list s,p
if(i == 1){
	s = PtrL;
	if(PtrL != NULL)
		PtrL = PtrL -> Next;
	else return NULL;
	free(s);
	return PtrL
}
p = FindKth(i-1,PtrL);//找到第i-1个的指针 找到前一个节点
if(p == NULL){
printf("参数错")return NULL}else if(p->Next == NULL){
 printf("这个指向的节点不存在");//最后一个节点是删不了的
 }else{
	s = P->Next;
	p->Next = S->Next;
	free(s);
	return Ptrl;
}

}
  1. 栈ADT
    堆栈是什么:逻辑结构还是存储结构
    栈的应用情况:后缀表达式,从左到右然后逐个运算 所以对于这种运算,顺序储存运算数 然后倒序输出 。
    定义: 具有一定约束的线性表,只在顶端进行插入 删除。
    插入数据:入栈 删除数据 出栈 后入先出的规则
//数组实现
//一个一维数组 加一个记录栈顶元素位置的变量
#define MAXSIZE 
typedef struct SNode *Stack;
struct SNode{
	ElementType Data[MaxSize];
	int Top;// 数组下表 栈顶的
}
//入栈
void push(Stack PtrS,ElementType item){
if(PtrS->Top == MAXSIZE -1 ){
	printf("堆栈满")return}else{
PtrS->Data[++(PtrS->Top)] = item;
}
}
//出栈
//return 一个值 top减一
void pop(Stack PtrS){
if(PtrS->Top ==  -1 ){
	printf("堆栈空")return ERROR;
}else{
return(PtrS->Data[(PtrS->Top)--]));// 直接修改了数组的size;
//栈顶少一
 }}
// 一个数组实现两个堆栈
#define MAXSIZE;
structure Dstack{
Elementype Data[MaxSize];
int Top1;//。栈顶指针
int Top2;// 栈顶指针
}
S.top1=-1;//起始值
S.top2 = MaxSize;//起始值

//push 
void Push(struct DStack *PtrS,Element type item,int Tag){
if(Ptrs->Top2 - PtrS->Top1 ==1){
printf("堆栈满")returnif(Tag == 1)
PtrS->Data[++(PtrS->Top1)] = item;
else 
PtrS->Data[--(PtrS->Top2)] = item;
}
}
// 出栈
void pop(stuct DStack *PtrS,int Tag){
if(Tag == 1){
if(PtrS->Top1 == -1){
	printf("堆栈1空")return NULL}
else{
return Ptrs->Data[(PtrS->Top1)--];
}
}
else{
if(PtrS->Top2 == MaxSize){
	printf("堆栈2空")return NULL}
else{
return Ptrs->Data[(PtrS->Top1)++];
}
}
}
}

利用链表实现栈:
单链表 插入和删除只能在栈顶进行。
所以用单向链表的头 做栈顶(删除和插入都比较方便)链尾不行

// 定义
typedef struct Snode *Stack;
struct Snode{
	ElementType Data;
	struct Snode *Next;//这种类型的指针
}
//建立一个栈
Stack CreatStack(){
	Stack S;
	S = (Stack)Malloc(sizeof(struct SNode));
	s->Next = NUll;
	return S;
}
// 判断堆栈是否是空
int Isempty(Stack S){
return (S->Next == NULL);
}
//push 
Void Push(ElementType item, Stack S){
struct Snode *tepcell ;// 定义一个临时的
Tepcell = (Struct Snode *)Malloc(sizeof(struct Snode));//给临时指针分配空间
Tepcell -> Element = item;
Tepcell -> Next = S->Next;//指向的变换
S->Tepcell = Tepcell;//更改头指针
}
// pop
ElementType Pop(Stack S){
struct Snode *Firstcell ;// 定义一个临时的
ElementType TopElem;
if(Isempty(S)){
printf("栈空")return NULL}
else{
FirstCell = S->Next;
S->Next = FirstCell ->Next;
TopElem = FirstCell->Element;
free(FirstCell);//释放空间
return TopElem;
}
}

堆栈的用途:实现函数调用以及递归的实现
5. 队列ADT
受限制的线性表 先进先出表 queue
入队:一端
出队:另一端

//顺序存储定义
#define MaxSize 
struct QNode{
ElementType Data[MaxSize];
int rear;//队列尾巴
int front;//队列头 其实是头一个前一个哈哈哈
}typedef struct QNode *Queue;

// 环形队列
// 空满都会导致front rear相等 n种状态区分n+1种状态 增加额外的标记 size or tag或者是不放满
void addQ(Queue PtrQ,ElementType X){
//只用数组n-1个空间
//进行判别
if((PtrQ->rear+1)%Maxsize == PtrQ->front){
printf("队列满")return}
PtrQ -> rear = (PtrQ-> rear+1)%Maxsize;
PtrQ -> Data[PtrQ->rear] = item
}
// 出队 
elementType deleteQ(Queue PtrQ){
if(PtrQ->front == PtrQ-> rear){
	printf(“队列空")return ERROR;
}else{
PtrQ->front = (PtrQ->front +1)%MaxSize;
return PtrQ->Data[PtrQ->front];
}
}

链表实现队列

//定义:单链表的尾巴不适合删除 
// 头删 尾入
struct Node{
ElementType Data;
struct Node *Next;
};
struct QNode{
//代表队列的结构
struct Node *rear;//队尾
struct Node *front;//队头
};
typedef struct QNode *Queue;
Queue PtrQ;

//出队
ElementType DeleteQ(Queue PtrQ){
struct Node *Frontcell
ElementType FrontElem;
if(PtrQ-> front== NULL)
{
printf("队列空")return ERROR;
}
FrontCell = PtrQ->front;
if(PtrQ->front == PtrQ->rear)
	PtrQ-> front = PtrQ->rear = NULL;
else
	PtrQ->front = PtrQ -> front -> Next;
FrontELem = FrontCell->Data;//需要独立 取出来
free(Frontcell);
return FrontElem;	
}

5: 线性表的总结:
多项式相加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值