您的位置:首页 > 理论基础 > 数据结构算法

数据结构面试之四——队列的常见操作

2014-03-08 10:06 387 查看


数据结构面试之四——队列的常见操作

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。

四、队列的基本操作

1.用数组构造队列

队列即是满足先进先出的链表。用数组存储的话,同样需要满足队列头front出栈,队列末尾rear入栈。而对于数组来讲,rear和front可以代表数组头和尾。不能简单的固定rear和front的大小为maxSize和0,因为可能出现中间元素为空的现象。所以,对于数组队列来讲,可以想象成环式存储,因为每一次入队后rear+1,每一次出队后front+1。这就需要控制front和rear的大小,每一次修改只要满足front=(front+1)%maxSize,rear=(rear+1)%maxSize即可满足要求。

同样需要注意:入队操作前先判定队列是否已经满;出队操作前先判定队列是否为空。

[cpp] view
plaincopy

template<typename Type>

class arrQueue

{

public:

arrQueue(intnSize=100);

~arrQueue();

arrQueue(constarrQueue<Type>& copyQueue);

arrQueue&operator=(const arrQueue<Type>& otherQueue);

voidinitializeQueue();

void destroyQueue();

bool isQueueEmpty();

bool isQueueFull();

void addQueue(constType& item);

void deQueue(Type&deletedItem);

private:

int maxSize;

int rear;

int front;

Type* list;

};

template<typename Type>

arrQueue<Type>::arrQueue(int nSize=100)

{

if(nSize < 0)

{

nSize = 100;

list = newType[nSize];

front = 0;

rear = 0;

maxSize = 100;

}

else

{

list = newType[nSize];

front = 0;

rear = 0;

maxSize =nSize;

}

}

template<typename Type>

arrQueue<Type>::~arrQueue()

{

if(!list)

{

delete[]list; //注意数组的删除,为delete []list;

list = NULL;

}

}

template<typename Type>

arrQueue<Type>::arrQueue(const arrQueue<Type>©Queue)

{

maxSize =copyQueue.maxSize;

front =copyQueue.front;

rear = copyQueue.rear;

list = newType[maxSize]; //注意需要自定义大小,容易出错.

for( int i = 0; i <rear; i++)

{

list[i] =copyQueue.list[i];

}

}

template<typename Type>

arrQueue<Type>& arrQueue<Type>::operator=(constarrQueue<Type>& otherQueue)

{

if(this ==&otherQueue)

{

cout <<"can't copy oneSelf!" << endl;

return *this;

}

else

{

if(maxSize !=otherQueue.maxSize)

{

cout<< "The Size of two Queue are not equal!" << endl;

return*this;

}

else

{

maxSize= otherQueue.maxSize;

front =otherQueue.front;

rear =otherQueue.rear;

for( inti = 0; i < rear; i++)

{

list[i]= otherQueue.list[i];

}//endfor

return*this;

}

}//end else

}

template<typename Type>

void arrQueue<Type>::initializeQueue()

{

destroyQueue();

}

template<typename Type>

void arrQueue<Type>::destroyQueue()

{

front = 0;

rear = 0;

}

//栈空的判定标志rear==front[初始]

template<typename Type>

bool arrQueue<Type>::isQueueEmpty()

{

return (rear ==front);

}

//空余1位作为判定位,可以把存储结构想象成环!

//注意栈满的判定:1.保证空间都被占用;

//2.保证rear的下一个位置=front即为满。

template<typename Type>

bool arrQueue<Type>::isQueueFull()

{

return((rear+1)%maxSize == front);

}

template<typename Type>

void arrQueue<Type>::addQueue(const Type& item)

{

if(!isQueueFull())

{

list[rear] =item;

rear =(rear+1)%maxSize;

cout << item<< " was added to Queue!" << endl;

}

else

{

cout <<"The Queue was already Full!" << endl;

}

}

template<typename Type>

void arrQueue<Type>::deQueue(Type& deletedItem)

{

if(!isQueueEmpty())

{

deletedItem =list[front];

front =(front+1)%maxSize; //注意此处的判定!

cout <<deletedItem << " was deleted from Queue!" << endl;

}

else

{

cout <<"The Queue was already Empty!" << endl;

}

}

2.队列采用链表链式存储结构

注意:1)此时的front和rear都变成了指针,front变成了头结点指针,而rear变成了尾节点的指针。2)此处的front和rear类似于链表操作中的first和last。3)入队实现主要在队列尾部实现,需要调整rear指针的指向;而出队操作主要在队头实现,需要调整front指针的指向。

[cpp] view
plaincopy

template<typename Type>

struct nodeType

{

Type info;

nodeType* link;

};

template<typename Type>

class linkedQueue

{

public:

linkedQueue();

~linkedQueue();

linkedQueue(constlinkedQueue<Type>&);

linkedQueue&operator=(const linkedQueue<Type>&);

voidinitializeQueue();

void destroyQueue();

bool isQueueEmpty()const;

bool isQueueFull()const;

void addQueue(constType& item);

void deQueue(Type&poppedItem);

void nodeCount();

private:

nodeType<Type>*rear;

nodeType<Type>*front;

int count; //统计节点个数

};

template<typename Type>

linkedQueue<Type>::linkedQueue()

{

count = 0;

front = NULL;

rear = NULL;

}

template<typename Type>

linkedQueue<Type>::~linkedQueue()

{

while( front != NULL )

{

nodeType<Type>*tempNode = new nodeType<Type>;

tempNode =front;

front =front->link;

deletetempNode;

}

//注意rear的清空

rear = NULL;

}

template<typename Type>

linkedQueue<Type>::linkedQueue(constlinkedQueue<Type>& copyQueue)

{

if(copyQueue.front !=NULL)

{

nodeType<Type>*current;

nodeType<Type>*first;

nodeType<Type>*newNode;

front = newnodeType<Type>;

front->info= copyQueue.front->info; //此处的top不能直接用,内存报错!

front->link= copyQueue.front->link;

first =front; //first跟进当前链表...

current =copyQueue.front->link; //current跟进copy链表...

while( current!= NULL)

{

newNode= new nodeType<Type>;

newNode->link= current->link;

newNode->info= current->info;

first->link= newNode;

first =newNode;

current= current->link;

}//end while

rear = current;

count =copyQueue.count;

}//end if

else

{

front = NULL;

rear = NULL;

count = 0;

}

}

template<typename Type>

linkedQueue<Type>& linkedQueue<Type>::operator=(constlinkedQueue<Type>& otherQueue)

{

//1避免自身赋值

if(this ==&otherQueue)

{

cout <<"Can't copy oneself!" << endl;

return *this;

}

//2其他

else

{

if(front !=NULL)

{

destroyQueue();

}

if(otherQueue.front!= NULL)

{

nodeType<Type>*current;

nodeType<Type>*first;

nodeType<Type>*newNode;

front =new nodeType<Type>;

front->info= otherQueue.front->info;

front->link= otherQueue.front->link;

first =front; //first跟进当前链表...

current= otherQueue.front->link; //current跟进copy链表...

while(current != NULL)

{

newNode= new nodeType<Type>;

newNode->link= current->link;

newNode->info= current->info;

first->link= newNode;

first= newNode;

current= current->link;

}//endwhile

rear =current;

count =otherQueue.count;

}//end if

else

{

front =NULL;

rear =NULL;

count =0;

}

return *this;

}

}

template<typename Type>

void linkedQueue<Type>::initializeQueue()

{

destroyQueue();

}

template<typename Type>

void linkedQueue<Type>::destroyQueue()

{

count = 0;

//注意此处的销毁工作:需要循环判定!

while(front != NULL)

{

nodeType<Type>*temp = new nodeType<Type>;

temp = front;

front =front->link;

}

rear = NULL;

}

template<typename Type>

bool linkedQueue<Type>::isQueueEmpty() const

{

return (front ==NULL);

}

template<typename Type>

bool linkedQueue<Type>::isQueueFull() const //空间非固定,动态申请!

{

return false;

}

template<typename Type>

void linkedQueue<Type>::addQueue(const Type& item)

{

if(!isQueueFull())

{

nodeType<Type>*newNode = new nodeType<Type>;

newNode->info= item;

newNode->link= NULL;

if(front ==NULL)

{

front =newNode;

rear =newNode;

}

else

{

rear->link= newNode;

rear =newNode;

}

count++;

cout <<item << " was pushed!" << endl;

}

}

template<typename Type>

void linkedQueue<Type>::deQueue(Type& deletedItem)

{

if(!isQueueEmpty())

{

nodeType<Type>*temp = new nodeType<Type>;

temp = front;

deletedItem =front->info;

front =front->link;

count--;

cout <<deletedItem << " was popped!" << endl;

delete temp;

}

}

template<typename Type>

void linkedQueue<Type>::nodeCount()

{

cout <<"nodeCount = " << count << endl;

}

3.用栈实现队列

注意栈是先进后出,而用两个栈:栈1先进后出,栈2在栈1的基础上先进后出,就能实现了先进先出。

注意:入队addtoQueue要保证将元素放入到栈1中;而对于出队deQueue要保证将栈1的全部元素出栈pop,然后再全部入栈2,最后执行出栈2操作即可。

[cpp] view
plaincopy

#include"linkedStack.h"

template<typename Type>

class stackedQueue

{

public:

stackedQueue();

~stackedQueue();

void addQueue(Type item);

void deQueue(Type deletedItem);

bool isQueueEmpty();

bool isQueueFull();

private:

nodeType<Type>* front;

nodeType<Type>* rear;

linkedStack<Type>* firstStack;

linkedStack<Type>* secondStack;

int nodeCnt; //记录节点个数

};

template<typename Type>

stackedQueue<Type>::stackedQueue()

{

front = NULL;

rear = NULL;

nodeCnt = 0;

firstStack = new linkedStack<Type>;

secondStack = new linkedStack<Type>;

}

template<typename Type>

stackedQueue<Type>::~stackedQueue()

{

while(front != NULL)

{

nodeType<Type>* temp;

temp = front;

front = front->link;

}

rear = NULL;

if(firstStack != NULL)

{

delete firstStack;

firstStack = NULL;

}

if(secondStack != NULL)

{

delete secondStack;

secondStack = NULL;

}

}

template<typename Type>

voidstackedQueue<Type>::addQueue(Type item)

{

if(!isQueueFull())

{

nodeCnt++;

firstStack->push(item); //单个入栈1

cout << item << " was added toQueue!" << endl;

}

}

template<typename Type>

voidstackedQueue<Type>::deQueue(Type deletedItem)

{

if(!isQueueEmpty())

{

while(!firstStack->isStackEmpty())

{

firstStack->pop(deletedItem); //全部出栈1

if(!firstStack->isStackFull())

{

secondStack->push(deletedItem); //全部入栈2

}

}

if(!secondStack->isStackEmpty())

{

secondStack->pop(deletedItem); //单个出栈2

}

cout << deletedItem << " was out ofQueue!" << endl;

nodeCnt--;

}

}

template<typename Type>

boolstackedQueue<Type>::isQueueEmpty()

{

return (nodeCnt == 0);

}

template<typename Type>

boolstackedQueue<Type>::isQueueFull()

{

return false;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: