数据结构 (二) -- 线性表 栈 队列

转载luofang师姐以及网上的一些玩意


链表存在空节点


栈不需要空


线性表

线性表的定义和特点
由n个数据特性相同的元素构成的有序序列称为线性表。特殊的,当n=0的时候,为空表.
特点:(对于非空的线性表或线性结构)
(1)存在唯一一个被称为“第一个”的数据元素
(2)存在唯一一个被称为“最后一个”的数据元素
(3)除第一个之外,结构中的每一个数据均只有一个前驱
(4)除了最后一个之外,结构中的每一个数据均只有一个后继

顺序表

代码声明:

#define Maxsize 100	//线性表可能达到的最大长度
typedef struct 
{
	ElemType *elem;	//存储空间的基地址
	int length;			//当前长度
}Sqlist;				//顺序表的数据结构类型为Sqlist

初始化

Status InitList(Sqlist &L)
{//构造一个空的顺序表L
	L.elem  =new ElemType[Maxsize];	 //为顺序表分配一个大小为Maxsize的数组空间
	if(!L.elem) exit(OVERFLOW);     //存储分配失败退出
	L.length=0;					//空表长度为0
}

取值

Status GetELem(Sqlist &L,int i)
{
	if(i<1||i>L.length) return ERROR;   //判断i取值是否合理
	e=L.elem[i-1];
	return OK;
}

查找

int Locate(Sqlist &L,ElemType e)
{
	for(int i=0;i<L.length;i++)
	{
		if(L.elem[i]==e)
			return i+1;
	}
	 return 0;
}

插入

Status ListInsert(SqList &L,int i,int e)
{
	if(i<1||i>L.length+1) return ERROR;
	if(L.lengrh==Maxszie) return ERROR;
	for(int j=L.length-1;j>=i-1;j--)
	{
		L.elem[j+1]=L.elem[j];
	}
	L.elem[i-1]=e;
	L.length++;
	return OK;
}

删除

Status ListDelete(Sqlist &L,int i)
{
	if(i<1||i>L.length) return ERROR;
	for(int j=i;j<=L.length-1;j++)
	{
		L.elem[j-1]=L.elem[j];
	}
	--L.length;
	return OK;
}

单链表

声明

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

初始化

Status InitList(LinkList &L)
{
	L=new LNode;		//生成新的结点作为头结点,用指针L指向头结点
	L->next=NULL;	//头结点的指针域置空
	return OK;
}

取值

Status GetElem(LinkList &L,int i,ElemType &e)
{
	LinkList p=L->next;  //用p指向首元节点
	j=1;	//j作为计数器
	while(p&&j<i)
	{
		p=p->next;
		++j;
	}
	if(!p||j>i)
		return ERROR;
	e=p->data;
	return OK;
}

查找

LNode *LocateElem(LinkList &L,ElemType e)
{
	p=L->next;
	while(p&&p->data!=e)
	{
		p=p->next;
	}
	return p;
}

插入

Status LinkInsert(LinkList &L,int i,ElemType e)
{//在带头结点的单链表L中第i个位置插入元素为e的新节点
	s=new LNode;
	s->data=e;
	p=L;
	j=0;
	while(p&&j<i-1)  //查找第i-1个节点,p指向该节点
	{
		p=p->next;
		++j;
	}
	if(!p||j>i-1) return ERROR;
	s->next=p->next;
	p->next=s;
	return 0K;
}

删除

Status ListDelete(LinkList &L,int i)
{
	//在带头结点的单链表中删除第i个节点
	p=L;
	j=0;
	while((p->next)&&(j<i-1))
	{
		p=p->next;
		j++;
	}
	if(!(p->next)||(j>i-1)) return ERROR;
	q=p->next;	//保存待删除的节点
	p->next=p->next->next;
	delete q;
	return OK;
}

创建单链表:

注意:单链表的创建和单链表的初始化有什么不同:单链表的初始化是创建一个只有头结点的空链表,单链表的创建是创建一个包含多个节点的单链表。即从空表的状态开始,依次建立各元素的节点,并逐个插入到链表中。
根据插入位置的不同,分为前插法和后插法
(1)前插法(显然,算法的时间复杂度为O(n))

void CreatList_H(LinkList &L,int n)
{
	//逆位序输入n个元素的值,建立带头结点的单链表
	L=new LNode;
	L->next=NULL;
	for(int i=0;i<n;i++)
	{
		p=new LNode;
		cin>>p->data;
		p->next=L-next;
		L-next=p;
	}
}

(2)后插法(算法的时间复杂度仍是O(n) )
为了使新节点能够插入到链表尾,所以需要增加一个新指针r指向链表的尾结点

void CreatList(LinkList &L,int n)
{
	L=new LNode;
	L->next=NULL;
	r=L;
	for(int i=0;i<n;i++)
	{
		p=new LNode;
		cin>>p->data;
		p->next=NULL;
		r->next=p;
		r=p;
	}
}

循环链表

声明:

typedef struct DuLNode
{
	ElemType data;
	struct DuLNode *prior;
	struct DuLNode *next;
}DuLNode,*DuLinkList;

栈:先进后出

顺序栈表示

#define Maxsize 100
typedef struct 
{
	SElemType *top;
	SElemType *base;
	int stackSize;
}SqStack;

敲黑板

初始化

Status InitSatck(SqStack &s)
{
	s.base=new SElemType[Maxsize];
	if(!s.base) return ERROR;
	s.top=s.base;
	s.stackSize=Maxsize;
	return OK;
}

入栈

Status Push(SqStack &s,SElemType e)
{
	if(s.top-s.base==Maxsize) return ERROR;
	*s.top++=e;
	return OK;
}

出栈

Status Pop(SqStack &s,SElemType &e)
{
	if(s.top==s.base) return ERROR;
	e=*--top;
	return OK;
}

取栈顶

SElemType GeTop(SqStack &s)
{
	if(s.top!=s.base) 
	{
		p=s.top;
		return *--p;
	}
}

链栈表示

typedef struct StackNode
{
	ElemType data;
	struct StackNode *next;
}StackNode,*LinkStack;

初始化

Status InitStack(LinkStack &s)
{
	s=NULL;
	return OK;
}

入栈

Status Push(LinkStack &s,SElemType e)
{
	p=new StackNode;
	p->data=e;
	p->next=s;
	s=p;
	return 0K;
}

出栈

status Pop(LinkStack &s,SElemType &e)
{
	if(s==NULL) return ERROR;
	e=s->data;
	p=s;
	s=s->next;
	delete p;
	return OK;
}

取栈顶

SElemType GeTop(LinkStack &s)

{
	if(s!=NULL)
		return s->data;
}

顺序循环队列的表示

#define Maxsize 100
typedef struct 
{
	QElemType *base;   //存储空间的基地址
	int rear;
	int front;
}SqQueue;


在这里插入图片描述

初始化

Status InitQueue(SqQueue &Q)
{
	Q.base=new QElemType[Maxsize];
	if(!Q.base) return ERROR;
	Q.front=Q.rear=0;
	return OK;
}

求长度

int QueueLength(SqQueue &Q)
{
	return  (Q.rear-Q.front+Maxsie)%Maxsize;
}

入队

Status EnQueue(SqQueue &Q,QElemType e)
{
	if((Q.rear+1)%Maxsize==Q.front) return ERROR;   //队满
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%Maxsize;
	return OK;
}

出队

Status DeQueue(SQueue &Q,QElemType &e)
{
	if(Q.rear==Q.front) return ERROR;  //队空
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%Maxsize;
	return OK;
}

取头元素

QElemType GetTop(SQueue &Q)
{
	if(Q.rear!=Q.front)
		return Q.base[Q.front];
}

链队

typedef struct QNode
{
	QElemType data;
	struct ONode *next;
}QNode,*QueuePtr;

typedef struct 
{
	QNode *front;
	QNode *rear;
}LinkQueue;

初始化

status InitQueue(LinkQueue &Q)
{
	Q.front=Q.rear=new QNode;
	Q.front->next=NULL;
	return OK;
}

入队

status EnQueue(LinkQueue &Q,QElemType e)
{
	p=new QNode;
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p
	return OK;
}

出队

status DeQueue(LinkQueue &Q,QElemType &e)
{
	if(Q.rear==Q.front) return OK;
	p=Q.front->next;
	e=p->data;
	Q.front->next=p->next;  //修改头指针
	if(Q.rear=p) Q.rear=Q.font;   //如果最后一个元素被删
	delete p;
	return OK;
}

取头顶

QElemType GeTop(LinkQueue &Q)
{
	if(Q.rear!=Q.front)
		return Q.front->next->data;
}

猜你喜欢

转载自blog.csdn.net/Touale/article/details/112547064