线性结构总结

线性结构

(一)线性表

它不仅仅是数组或者链表,它是一个结构体,结构体里面包含有数据数组和线性表的大小。

顺序存储

使用数组进行存储
1)首先需要定义一个结构体,包含数据数组和线性表的大小(使用last作为标记)。

注意事项:
1、初始化线性表就是为它开辟一片空间。
2、PtrL->last中的->针对指向结构体的指针,而成员访问符.是针对于结构体变量。
3、在进行插入操作的时候应该考虑到原本的空间是否已经满、插入的位置是否合法。
4、并且增加和删除元素之后,记得更新last的值。

//线性表的顺序存储结构//

//建立之前需要建立一个结构体//
typedef struct LNode *List; 
struct LNode{//整个线性表被包含在这个结构体中// 
	Elementype Data[MAXSIZE];
	int last//用于存储顺序表的大小// 
}L;

List PtrL;//用PtrL指向结构体// 

//操作一:建立一个顺序表,初始化//
List MakeEmpty()
{
	PtrL=(List)malloc(sizeof(struct LNode));
	PtrL->last=-1;
	return PtrL;
}

//操作二:查找元素//
int Find(int X;List PrtL)
{
	int i=0;
	while(i<=PtrL->last&&PtrL->Data[i]!=X) 
	{
		i++;
	}
	if(i>PtrL->last)
		return -1;
	else 
		return i;	
}

//操作三:插入——先移动再插入//
void Insert(int X,int i,List PrtL)//在第i个位置插入X
{
	if(PrtL->last==MAXSIZE-1)
	{ 
		pritnf("表已经满了");
		return;
	}
	if(i<1||i>PrtL->last+2)//判断插入的位置是否合法
	{
		printf("位置不合法");
		return; 
	}
	int j;
	for(j=PrtL->last;j>=i-1;j--)
	{
		PrtL->Data[j+1]=PrtL->Data[j];
	}
	PrtL->Data[i-1]=X;
	PrtL->last++;
	return;
} 

//操作四:删除元素//
void Delete(int i,List PrtL)//删除第i个位置的元素// 
{
	if(i<1||i>PrtL->last+1)
	{
		printf("不存在第i个元素")
		return; 
	}
	int j;
	for(j=i-1;j<=PrtL->last;j++)
	{
		PrtL->Data[i-1]=PrtL->Data[i];
	}
	PrtL->last--;//删完之后别忘了将last值减去 // 
	return;
} 

链式存储

使用链表进行存储
1)仍然需要定义一个结构体,里面包含数据和指向下一个结点的指针。

注意事项:
1、对于一切插入操作,首先应想到插入内容的本质,比如插入结点,那么首先就得构建一个结点,分配空间。
2、对于链表,插入的位置有区别,链表头和其他位置有不同,需单独考虑。
3、在进行删除操作的时候也应该注意表头和其他位置的不同,并且需要有一个指针指向被删除的结点,然后 free。

//线性表的链式存储结构//
typedef struct LNode *List;
struct LNode{
	int data;
	List next;
}L;
List PrtL;
//因为是自定义类型,List本身就是一个指向结点的指针所以不是*PrtL 

//操作一:求表长//
int length(List PrtL)
{
	int i=0;
	List p=PrtL;//p指向表中的第一个结点// 
	while(PrtL!=NULL)
	{
		i++;
		PrtL=PrtL->next;	
	}
	return i; 
}

//操作二:查找//
//按照序号查找//
List FindKth(int K,List PrtL) 
{
	List p=PrtL;
	int i=0;
	while(i<k&&p!=NULL)
	{
		i++;
		p=p->next;
	}
	if(i==k)
		return p;
	else
		return NULL;
}

//按照值查找//
List Find(ElementType X,List PrtL)
{
	List p=PrtL;
	while(p)
	{
		if(p->data==X)
			return p;
		p=p->next;
	}
	return NULL;
} 

//操作三:插入//
List Insert(ElementType X,int i,List PrtL)//在第i个位置插入元素X//
{
	List s=malloc(sizeof(struct LNode));//构建预插入结点// 
	s->data=X;
	
	if(i==1)
	{
		s->next=PrtL;
		return s;
	}
	
	List p=PrtL;//指向第一个结点// 
	int j=0;
	while(j<i-2)
	{
		j++;
		p=p->next;
		if(!p)
			return NULL;
	}
	s->next=p->next;
	p->next=s;
	return PrtL;
} 

//操作四:删除//
List Delete(int i,List PrtL)
{
	List p,s;
	if(i==1)//如果是删除第一个结点// 
	{
		List s=PrtL;
		if(!PrtL)
			return NULL;
		else
			PrtL=PrtL->next;
		free(s);//一定要有free的操作// 
		return  PrtL;
	}

	p=FindKth(i-1,PrtL);
	if(!p)
		return NULL;
	else if(!p->next)
		return NULL;
	else
	{
		s=p->next;//首先将结点定位好// 
		p->next=s->next;
		free(s);
		return PrtL;
	}	
} 

(二)堆栈

与线性表一样,堆栈也是一个结构体,里面包含一个一维数组和存储栈顶元素位置的变量。

顺序存储

使用数组进行堆栈的存储

注意事项:
1、在使用堆栈的时候应当先进行初始化操作。
2、入栈相当于插入,所以应判断堆栈是否满了。
3、出栈相当于删除,应判断删除的元素是否合法,也就是是否堆栈是空的。
4、遇到先pop出来top标记再减掉的情况可以,写在同一个表达式中。

//堆栈的顺序存储结构//
typedef struct SNode *Stack;
struct SNode{
	ElementType Data[MAX];
	int top; 
};

//操作一:入栈//
void Push(Stack PrtS,ElementType item){
	
	PrtS=malloc(sizeof(struct SNode));
	PrtS->top=-1;//初始化堆栈//
	
	if(PrtS->top==MAX-1)
	{
		printf("堆栈已满")return; 
	}
	else
	{
		PrtS->Data[++(PrtS->top)]=item;
		return;
	} 
}

//操作二:出栈//
ElementType Pop(Stack PrtS){
	if(PrtS->top==-1)
		return ERROR;
	else
		return PrtS->Data[(PrtS->top)--]; 
} 

链式存储

使用链表进行存储
1)同样使用结构体,但是结构体里面存储的就是数据和指向下一节点的指针,不是数据数组。

注意事项:
1、结点或者链表在进行初始化的时候应当将next指针置为NULL。
2、堆栈的链式存储top指针应该放在表头,head和第一个数据节点之间,top如果放在尾端,则删除的时候无法找到前端指针。

//堆栈的链式存储结构//
typedef struct SNode *Stack;
struct SNode{
	ElementTpye Data;
	Stack next;
};  

//操作一:初始化//
Stack Creat(){
	Stack S;//指向结点//
	S=malloc(sizeof(struct SNode));
	S->next=NULL;
	return S;
}

//操作二:判断是否为空//
int IsEmpty(Stack S){
	return (S->next==NULL);//为空的话就返回整数1// 
}

//操作三:入栈//
void Push(ElementType X,Stack S){
	struct SNode New=malloc(sizeof(struct SNode));
	New->Data=X;
	New->next=NULL;//初始化结点//
	
	New->next=S->next;
	S->next=New;
	return;
}

//操作四:出栈//
ElementType Pop(Stack S){
	struct SNode *Delete;//删除元素,需要释放空间,则需要定义一个指针// 
	if(!S->next)
		return ERROR;
	else
	{
		Delete=S->next;
		S->next=Delete->next;
		free(Delete);
		return Delete->Data;
	}
}

(三)队列

同样使用结构体包装整个队列

顺序存储

使用数组存储,结构体中包含一个一维数组和front和rear标记

//队列的顺序存储//
typedef struct QNode *Queue;
struct QNode{
	ElementType Data[MAX];
	int front;
	int rear;
};

//操作一:初始化//
Queue creat(){
	Queue Q=malloc(sizeof(struct QNode));
	front=-1;
	rear=-1;
	return Q;
}

//操作二:入队,出队//
void Add(Queue PtrQ,ElementType item){
	if("队列满了")
		return;
	else
		PtrQ->Data[++(PtrQ->rear)]=item;
} 

ElementType Pop(Queue PtrQ){
	if(PtrQ->front==PtrQ->rear)
	{
		printf("队列是空的");
		return; 
	}
	else
		return PtrQ->Data[(PtrQ->front)++];
}

链式存储

链式存储需要两个结点,数据结点包含数据和指向下一结点指针,另一结点包含front和rear指针。
注意事项:
1、链式存储时front和rear分别位于表头和表尾,因为表头方便删除。

//队列的链式存储结构//
struct Node{
	ElementType data;
	struct Node *next;
};
struct QNode{
	struct Node *front;
	struct Node *rear;
};
typedef struct Node *Queue

//操作一:出队(无头结点)//
ElementType Delete(Queue PrtQ){
	struct Node *pop;
	pop=QNode->front;
	if("队列为空")
		return EORROR;
	else
	{
		pop->data=QNode->front->data;
		QNode->front=QNode->front->next;
		free(pop);
		return pop->data;
	} 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值