重构--使用双重指针做参数来写队列

本文是在  链式队列的基础操作实现(C语言)的基础上,将指针做参数改为双重指针做参数,以提高程序的灵活性。

/*------------------------------------------------
--目的:学习队列的创建及用法,链式存储实现
--作者:刘志强
--创建时间:2015-1-7
-------------------------------------------------*/
#include 
#include  

typedef int ElementType; 

/*------------------------------------------------
--创建队列节点及队的指针 
-------------------------------------------------*/
typedef struct Node {
	ElementType Data;
	struct Node *Next; 
}QueueNode;

typedef struct {
	QueueNode *rear;  //队尾指针一个 
	QueueNode *front; //队头指针一个 
}LinkQueue;

int flag_del=0;//标记删除空队列元素时,返回的多余的一个0 

 
/*------------------------------------------------
--功能函数;初始化队列 ,创建空队列 
-------------------------------------------------
LinkQueue* InitQueue (void)
{
	LinkQueue *Queue = (LinkQueue *) malloc(sizeof(LinkQueue));
	Queue->front=Queue->rear =NULL;
	//printf("初始化完成!\n");
	return Queue;
}*/
//方式 2: 
void InitQueue (LinkQueue** Queue)
{
	*Queue = (LinkQueue *) malloc(sizeof(LinkQueue));
	(*Queue)->front=(*Queue)->rear =NULL;
}

/*------------------------------------------------
--功能函数;元素 Element 进入队列 
-------------------------------------------------*/
void AddQueue (LinkQueue **Queue,ElementType Element) 
{
	QueueNode *temp = (QueueNode*) malloc(sizeof(QueueNode));
	if (temp) 
	{
		temp->Data = Element;
		temp->Next = NULL;
		if((*Queue)->front==NULL)
		{
			(*Queue)->front = (*Queue)->rear = temp;
			(*Queue)->rear->Next=temp->Next;
		}
		else
		{
			(*Queue)->rear->Next = temp;  //注意此句及后一句 
			(*Queue)->rear = temp;
			(*Queue)->rear->Next=temp->Next;				
		}		
	}	
}

/*------------------------------------------------
--功能函数;判断队列是否为空 
-------------------------------------------------*/
ElementType IsEmpty (LinkQueue **Queue)
{
	if((*Queue)->front == NULL)
	{
		printf("警告:队列为空!!!\n");
	}
	return (*Queue)->front == NULL; 
}


/*------------------------------------------------
--功能函数;创建队列 
-------------------------------------------------*/
void CreatQueue (LinkQueue **Queue) 
{
	ElementType temp;
	InitQueue (Queue);
	printf("请输入一组数字创建队列(注意:请按换行后Ctrl+Z再回车结束输入):\n");
	while(scanf("%d",&temp) != EOF)  //若不能安全结束循环会造成:内存满->电脑死机!!! 
		AddQueue (Queue,temp);
	printf("队列创建成功!\n"); 
}

/*------------------------------------------------
--功能函数;从队列中删除一个元素 
-------------------------------------------------*/
ElementType DeleteQueue(LinkQueue **Queue) 
{//带头结点的链式队列 ,每次删除头结点后面的一个元素 
	QueueNode *FrontCell;
	ElementType FrontElem;
	if (IsEmpty(Queue)==1)
	{
		flag_del=1;
		//可用flag标记法来除去多余的提示,在设计系统时可采用 		 
		return ;
	}
	FrontCell=(*Queue)->front;
	FrontElem=(*Queue)->front->Data;
	if((*Queue)->front==(*Queue)->rear)
		(*Queue)->front=(*Queue)->rear=NULL;
	else
		(*Queue)->front=(*Queue)->front->Next;	
	free(FrontCell);
	return FrontElem;	 
}

 /*------------------------------------------------
--功能函数;打印队列中的所有元素 
-------------------------------------------------*/
int Print (LinkQueue **Queue)
{
	QueueNode *TempCell;
	if ((*Queue)->front == NULL)
	{
		return ;  //不再执行此函数下面的程序 
	}		
	printf("队列中的所有元素为:\n"); 
	TempCell=(*Queue)->front;
	while(TempCell != (*Queue)->rear)  
    {  
        printf("%d ",TempCell->Data);  
        TempCell = TempCell->Next;  
    }  
    printf("%d",TempCell->Data);  
    printf("\n"); 
    return 0;
} 
/*------------------------------------------------
--功能函数;获取队列长度 
-------------------------------------------------*/
int GetQueueLength (LinkQueue **Queue) 
{
	/*因队头和队尾指针用指针变量定义
	注意不能使用指针改变数据结构 */ 
	int length=0;
	QueueNode *TempCell;
	TempCell = (*Queue)->front;
	if (IsEmpty(Queue)==1)
		return 0;
	while(TempCell->Next!=NULL)
	{
		QueueNode *Temp;      //交换思想 
		Temp=TempCell->Next;
		TempCell=Temp;
		length++; 
	}
	return length+1;
}

 /*------------------------------------------------
--功能函数;清空队列 
-------------------------------------------------*/
void ClearQueue (LinkQueue **Queue) 
{
	while(1)
	{
		QueueNode *FrontCell;
		if ((*Queue)->front == NULL)
			break;
		FrontCell=(*Queue)->front;
		if((*Queue)->front==(*Queue)->rear)
			(*Queue)->front=(*Queue)->rear=NULL;
		else
			(*Queue)->front=(*Queue)->front->Next;	
		free(FrontCell);
	}
	
	printf("队列已清空\n"); 
}

 /*------------------------------------------------
--功能函数;销毁队列 
-------------------------------------------------*/
void DestroyQueue (LinkQueue **Queue) 
{
	while(1)
	{
		QueueNode *FrontCell;
		if ((*Queue)->front == NULL)
			break;
		FrontCell=(*Queue)->front;
		if((*Queue)->front==(*Queue)->rear)
			(*Queue)->front=(*Queue)->rear=NULL;
		else
			(*Queue)->front=(*Queue)->front->Next;	
		free(FrontCell);
	} 
	free((*Queue)->front);
	//free(Queue->rear);
	printf("队列已销毁,请重新初始化!\n"); 
}

 /*------------------------------------------------
--功能函数;从队头中删除 i 个元素
-------------------------------------------------*/
//LinkQueue* DeleteAny (LinkQueue *Queue, int any) //返回新的链表 
int  DeleteAny (LinkQueue **Queue)
{
	if(IsEmpty(Queue))
	{
		//printf("队列已空,无需执行删除操作\n"); 
		return ;
	}
	else
	{
		int i=0,length=0;
		length = GetQueueLength(Queue);
		printf("请输入要删除元素的个数(范围:0 < i <= %d ):",length);
		scanf("%d",&i); 
		while(i<=0||i>length)
		{
			printf("输入范围不对,请重新输入");
			scanf("%d",&i);
		}//删除然后打印,或者储存到新的链表中已备后用 
		printf("删除元素为:");
		while(i)
		{
			printf("%d ",DeleteQueue(Queue));
			i--; 
		} 
	}
}
 /*------------------------------------------------
--功能函数;向队尾中添加 any 个元素
-------------------------------------------------*/
void AddAny (LinkQueue **Queue)
{
	printf("请输入要添加的数字(以空格区分不同数字,注意:请按换行后Ctrl+Z再回车结束输入):\n");
	ElementType temp;
	while(scanf("%d",&temp) != EOF)  //若不能安全结束循环会造成:内存满->电脑死机!!! 
		AddQueue (Queue,temp);
	printf("添加成功!\n");  
}




你可能感兴趣的:(数据结构与算法)