C语言双向链表队列标准模板

A "deque" is a data structure consisting of a list of items, on which the following operations are possible:

  • Push(X,D): Insert item X on the front end of deque D.
  • Pop(D): Remove the front item from deque D and return it.
  • Inject(X,D): Insert item X on the rear end of deque D.
  • Eject(D): Remove the rear item from deque D and return it. Write routines to support the deque that take O(1) time per operation.

Format of functions:

Deque CreateDeque();
int Push( ElementType X, Deque D );
ElementType Pop( Deque D );
int Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

where Deque is defined as the following:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Element;
    PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
    PtrToNode Front, Rear;
};

Here the deque is implemented by a doubly linked list with a header. Front and Rear point to the two ends of the deque respectively. Front always points to the header. The deque is empty when Front and Rear both point to the same dummy header. Note: Push and Inject are supposed to return 1 if the operations can be done successfully, or 0 if fail. If the deque is empty, Pop and Eject must return ERROR which is defined by the judge program.

 

这里的队列结构是一个结构体里面放了两个节点指针,一个指向队头,一个指向队尾,注意存在一个队头节点

Deque CreateDeque()
{
	Deque deque = (Deque)malloc(sizeof(struct DequeRecord));

	PtrToNode Head = (PtrToNode)malloc(sizeof(struct Node));    // 建立一个头节点
	Head->Last = NULL;
	Head->Next = NULL;

	deque->Front = Head;
	deque->Rear = Head;
	return deque;

}

表头插入元素

int Push(ElementType X, Deque D)   // 表头插入
{
	PtrToNode NewNode = (PtrToNode)malloc(sizeof(struct Node));
	NewNode->Element = X;

	// 空队列的情况,需要改变尾节点
	if (D->Front == D->Rear)
	{
		D->Front->Next = NewNode;
		NewNode->Last = D->Front;
		NewNode->Next = NULL;
		D->Rear = NewNode;
	}
	else
	{
		NewNode->Next = D->Front->Next;   // 插入尾节点
		NewNode->Last = D->Front;
		D->Front->Next->Last = NewNode;
		D->Front->Next = NewNode;
	}
	
	return 1;
}

表头删除

ElementType Pop(Deque D)   // 表头删除
{
	// 空链表的情况
	if (D->Front == D->Rear)
		return ERROR;

	PtrToNode Temp;    
	int X;            // 记录返回的值

	Temp = D->Front->Next;
	X = Temp->Element;

	// 只有一个节点的情况,要改变尾节点
	if (Temp->Next == NULL)
	{
		
		D->Front->Next = NULL;
		D->Rear = D->Front;
		free(Temp);
	}
	// 有两个以上节点的情况
	else
	{
		D->Front->Next = Temp->Next;
		Temp->Next->Last = D->Front;
		free(Temp);
	}
	return X;
}

表尾部插入

int Inject(ElementType X, Deque D)   // 表尾部插入
{
	PtrToNode NewNode = (PtrToNode)malloc(sizeof(struct Node));
	NewNode->Element = X;
	NewNode->Next = NULL;
	// 如果空队列的情况,要影响头节点
	if (D->Rear == D->Front)
	{
		D->Front->Next = NewNode;
		NewNode->Last = D->Front;
		D->Rear = NewNode;
	}
	
	else   // 不为空的情况,只改变尾节点
	{
		D->Rear->Next = NewNode;
		NewNode->Last = D->Rear;
		D->Rear = NewNode;
	}

	return X;
}

表尾部删除

ElementType Eject(Deque D)   // 表尾部删除
{
	if (D->Front == D->Rear)   // 如果空队列的情况
		return ERROR;

	PtrToNode Temp;
	int X;
	Temp = D->Rear;
	X = Temp->Element;

	D->Rear = Temp->Last;
	Temp->Last->Next = NULL;
	free(Temp);
	return X;
	
}

完整代码

#include 
#include 
#include 


#define ElementType int
#define ERROR 1e5
typedef enum { push, pop, inject, eject, end } Operation;

typedef struct Node *PtrToNode;
struct Node 
{
	ElementType Element;
	PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord 
{
	PtrToNode Front, Rear;
};
Deque CreateDeque();
int Push(ElementType X, Deque D);
ElementType Pop(Deque D);
int Inject(ElementType X, Deque D);
ElementType Eject(Deque D);

Operation GetOp();          /* details omitted */
void PrintDeque(Deque D); /* details omitted */

int main()
{
	ElementType X;
	Deque D;
	int done = 0;

	D = CreateDeque();
	while (!done) 
	{
		switch (GetOp()) 
		{
		case push:
			scanf_s("%d", &X);
			if (!Push(X, D)) 
				printf("Memory is Full!\n");
			break;
		case pop:
			X = Pop(D);
			if (X == ERROR) 
				printf("Deque is Empty!\n");
			break;
		case inject:
			scanf_s("%d", &X);
			if (!Inject(X, D)) 
				printf("Memory is Full!\n");
			break;
		case eject:
			X = Eject(D);
			if (X == ERROR) 
				printf("Deque is Empty!\n");
			break;
		case end:
			PrintDeque(D);
			done = 1;
			break;
		}
	}
	return 0;
}

/* Your function will be put here */
Deque CreateDeque()
{
	Deque deque = (Deque)malloc(sizeof(struct DequeRecord));

	PtrToNode Head = (PtrToNode)malloc(sizeof(struct Node));    // 建立一个头节点
	Head->Last = NULL;
	Head->Next = NULL;

	deque->Front = Head;
	deque->Rear = Head;
	return deque;

}


int Push(ElementType X, Deque D)   // 表头插入
{
	PtrToNode NewNode = (PtrToNode)malloc(sizeof(struct Node));
	NewNode->Element = X;

	// 空队列的情况,需要改变尾节点
	if (D->Front == D->Rear)
	{
		D->Front->Next = NewNode;
		NewNode->Last = D->Front;
		NewNode->Next = NULL;
		D->Rear = NewNode;
	}
	else
	{
		NewNode->Next = D->Front->Next;   // 插入尾节点
		NewNode->Last = D->Front;
		D->Front->Next->Last = NewNode;
		D->Front->Next = NewNode;
	}
	
	return 1;
}


ElementType Pop(Deque D)   // 表头删除
{
	// 空链表的情况
	if (D->Front == D->Rear)
		return ERROR;

	PtrToNode Temp;    
	int X;            // 记录返回的值

	Temp = D->Front->Next;
	X = Temp->Element;

	// 只有一个节点的情况,要改变尾节点
	if (Temp->Next == NULL)
	{
		
		D->Front->Next = NULL;
		D->Rear = D->Front;
		free(Temp);
	}
	// 有两个以上节点的情况
	else
	{
		D->Front->Next = Temp->Next;
		Temp->Next->Last = D->Front;
		free(Temp);
	}
	return X;
}

int Inject(ElementType X, Deque D)   // 表尾部插入
{
	PtrToNode NewNode = (PtrToNode)malloc(sizeof(struct Node));
	NewNode->Element = X;
	NewNode->Next = NULL;
	// 如果空队列的情况,要影响头节点
	if (D->Rear == D->Front)
	{
		D->Front->Next = NewNode;
		NewNode->Last = D->Front;
		D->Rear = NewNode;
	}
	
	else   // 不为空的情况,只改变尾节点
	{
		D->Rear->Next = NewNode;
		NewNode->Last = D->Rear;
		D->Rear = NewNode;
	}

	return X;
}

ElementType Eject(Deque D)   // 表尾部删除
{
	if (D->Front == D->Rear)   // 如果空队列的情况
		return ERROR;

	PtrToNode Temp;
	int X;
	Temp = D->Rear;
	X = Temp->Element;

	D->Rear = Temp->Last;
	Temp->Last->Next = NULL;
	free(Temp);
	return X;
	
}

 

你可能感兴趣的:(算法)