数据结构的奇妙冒险(C语言版)——线性结构(下)

目录

七、队列及实现

1、定义

2、队列的抽象数据类型描述

八、队列的顺序存储实现

1、定义结构体

2、入队列

3、出队列

九、队列存储的链式实现

1、定义结构体

2、不带头结点的链式队列

十、线性结构应用实例


七、队列及实现

1、定义

队列:具有一定操作约束的线性表

特点:

        ①插入和删除操作:只能在一端插入,在另一端删除

        ②数据插入:入队列(AddQ)

        ③数据删除:出队列(DeleteQ)

        ④先来先服务

        ⑤先进先出:FIFO

2、队列的抽象数据类型描述

类型名称:队列(Queue)

数据对象集:一个有0或多个元素的有穷线性表

操作集:长度为MaxSIze的队列Q\epsilonQueue,队列元素item\epsilonElementType

Queue CreatQueue(int MaxSize);//生成长度为MaxSize的空队列 
int IsFullQ(Queue Q,int MaxSize);//判断队列Q是否已满 
void AddQ(Queue Q,ElementType item);//将数据元素item插入队列Q中 
int IsEmptyQ(Queue Q);//判断队列Q是否为空 
ElementType DeleteQ(Queue Q);//将队头数据元素从队列中删除并返回 

八、队列的顺序存储实现

        队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成

1、定义结构体

#define MaxSize <存储数据元素的最大个数> 
typedef struct QNode *Queue;
struct QNode
{
	ElementType Data[MaxSize];
	int rear;//队列头元素
	int front;//队列尾元素
 };

2、入队列

void AddQ(Queue PtrQ,ElementType item)
{
	if((PtrQ->rear+1)%MaxSize==PtrQ->front)//取余用于实现循环队列
	{
		printf("队列满");
		return; 
	}
	PtrQ->rear=(PtrQ->rear+1)%MaxSize;
	PtrQ->Data[PtrQ->rear]=item;
}

3、出队列

ElementType DeleteQ(Queue PtrQ)
{
	if(PtrQ->front==PtrQ->rear)
	{
		printf("队列空");
		return ERROR; 
	}
	else 
	{
		PtrQ->front=(PtrQ->front+1)%MaxSize;
		return PtrQ->Data[PtrQ->front];
	}
}

九、队列存储的链式实现

        队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行。并将链表表头用作删除front,表尾做插入rear。

1、定义结构体

struct Node{
	ElementType Data;
	struct Node *Next;
}; //队列结点

struct QNode
{
	struct Node *rear;
	struct Node *front;
};//队列头尾指针
typedef struct QNode *Queue;
Queue PtrQ;

2、不带头结点的链式队列

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;
}

十、线性结构应用实例

多项式加法乘法运算:

      输入两个多项式,程序输出相乘以及相加的结果

样例:

输入

please input:2

1 2 2 1(表示有系数为1的2次项、系数为2的1次项,以此类推)

please input:2

1 2 2 1

输出:

1 4 4 3 4 2

2 2 4 1

思路:使用链表记录两多项式系数以及指数,将相同指数的项系数相加,其余部分进行拷贝,通过循环将两多项式相乘,将结果一个一个插入结果链表

#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

typedef struct PolyNode *Polynomial;
struct PolyNode
{
	int coef;
	int expon;
	Polynomial link;
 } ;
 
Polynomial ReadPoly();//输入多项式 
void Attach(int c,int e,Polynomial *pRear);//在pRear指向的结点后创建新结点并初始化 
Polynomial PolyAdd(Polynomial P1,Polynomial P2);//多项式相加 
Polynomial Mult(Polynomial P1,Polynomial P2);//多项式相乘 
void PrintPoly(Polynomial P);//多项式显示 
int Compare(int a,int b);//比大小 


int main(int argc, char *argv[]) {
	Polynomial P1,P2,PP,PS;
	P1=ReadPoly();//输入多项式1 
	P2=ReadPoly();//输入多项式2 
	PP=Mult(P1,P2);//多项式相乘 
	PrintPoly(PP);//输出相乘结果 
	PS=PolyAdd(P1,P2);//多项式相加 
	PrintPoly(PS);//输出相加结果 
	return 0;
}

Polynomial ReadPoly()
{
	Polynomial Rear,P,t;
	int c,e,N;
	//临时头结点创建 
	P=(Polynomial)malloc(sizeof(struct PolyNode));
	P->link=NULL;
	Rear=P;
	printf("Please input:");
	scanf("%d",&N);//N用于记录多项式的项数 
	while(N--)//输入多项式的参数 
	{
		scanf("%d%d",&c,&e);
		Attach(c,e,&Rear);
	}
	t=P;
	P=P->link;
	free(t);//释放临时头结点 
	return P;
}

void Attach(int c,int e,Polynomial *pRear)
{
	Polynomial P;
	
	P=(Polynomial)malloc(sizeof(struct PolyNode));
	P->coef=c;
	P->expon=e;
	P->link=NULL;
	(*pRear)->link=P;
	*pRear=P;
}

Polynomial PolyAdd(Polynomial P1,Polynomial P2)
{
	Polynomial front,rear,temp;//front头结点指针,rear尾指针 
	int sum;
	rear=(Polynomial)malloc(sizeof(struct PolyNode));
	front=rear;
	while(P1&&P2)
	{
		switch(Compare(P1->expon,P2->expon))
		{
			case 1:
				Attach(P1->coef,P1->expon,&rear);
				P1=P1->link;
				break;
			case -1:
				Attach(P2->coef,P2->expon,&rear);
				P2=P2->link;
				break;
			case 0: 
				sum=P1->coef+P2->coef;
				if(sum)Attach(sum,P1->expon,&rear);
				P1=P1->link;
				P2=P2->link;
				break;
		}
	}
	for(;P1;P1=P1->link)Attach(P1->coef,P1->expon,&rear);
	for(;P2;P2=P2->link)Attach(P2->coef,P2->expon,&rear);
	rear->link=NULL;
	temp=front;
	front=front->link;
	free(temp);
	return front;
}

Polynomial Mult(Polynomial P1,Polynomial P2)
{
	Polynomial P,Rear,t1,t2,t;
	int c,e;
	
	if(!P1||!P2) return NULL;
	
	t1=P1;t2=P2;
	P=(Polynomial)malloc(sizeof(struct PolyNode));
	P->link=NULL;
	Rear=P;
	//先将第一个多项式的第一项乘以第二个多项式的每一项,得到初始化的P链表,用于存储多项式相乘结果 
	while(t2)
	{
		Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
		t2=t2->link;
	}
	t1=t1->link;//由于第一项已经乘了。因而后续循环跳过第一项 
	//双循环遍历,并将结果存储在P链表 
	while(t1)
	{
		t2=P2;Rear=P;
		while(t2)
		{
			c=t1->coef*t2->coef;
			e=t1->expon+t2->expon;
			while(Rear->link&&Rear->link->expon>e)//按照指数从大到小存储,当Rear->link->expon<=e或者Rear->link=NULL时,结束循环 
				Rear=Rear->link;
			if(Rear->link&&Rear->link->expon==e)//若Rear->link->expon==e,即直接将系数相加即可 
			{
				if(Rear->link->coef+c)//如果系数相加为0 
					Rear->link->coef+=c;
				else 
				{
					t=Rear->link;
					Rear->link=t->link;
					free(t);
				}
			}
			else //若Rear->link->expon不为e,则需要创建新结点 
			{
				t=(Polynomial)malloc(sizeof(struct PolyNode));
				t->coef=c;t->expon=e;
				t->link=Rear->link;
				Rear->link=t;Rear=Rear->link;
			}
			t2=t2->link;
		}
		t1=t1->link;
	}
	t2=P;P=P->link;free(t2);//释放临时头结点 
	return P;
}

void PrintPoly(Polynomial P)
{
	int flag=0;
	if(!P){printf("0 0\n");return;
	}
	while(P)
	{
		if(!flag)//若是多项式的第一项,则将flag置1,其他情况输出空格 
			flag=1;
		else
			printf(" ");
		printf("%d %d",P->coef,P->expon);
		P=P->link;
	}
	printf("\n");
}

int Compare(int a,int b)
{
	if(a>b)
		return 1;
	else if(a=b)
		return 0;
	else return -1;
}



数据结构的奇妙冒险持续更新中~

要是文章有帮助的话

就点赞收藏关注一下啦!

感谢大家的观看

欢迎大家提出问题并指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IC 1396

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值