zoukankan      html  css  js  c++  java
  • 队列(Queue)

    最近学习了数据结构队列,队列是一种特殊的线性表,是被限定了的线性表,先进先出(FIFO, First in First out),跟栈的后进先出(LIFO, Last in First out)是类似的一种数据结构,对于这个数据结构,已经有很多的文章有过介绍了,这里也就不再赘述,直接贴出代码,希望能够互相进步!

    这里使用了一个HeadNode的节点来表示一个队列,里面只有两个信息,分别是指向队列队首和指向队列队尾的两个指针,这样写,个人认为会更加方便,也不需要进行一些指针的返回。

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    typedef int Elemtype;
    typedef struct node{
    	Elemtype data;
    	node *next;
    }Queue;
    typedef struct{
    	Queue *front, *end;
    }HeadNode;
    /*
     *1.初始化一个队列
     *2.入队
     *3.出队
     *4.获取队首元素
     *5.判断队列是否为空
     */
    bool isEmpty(HeadNode *hd) {
    	return (hd -> front == NULL ? true : false);
    }
    HeadNode *initQueue() {
    	HeadNode *p = new HeadNode;
    	if (p == NULL) {
    		cout << "分配内存失败!请重试!" << endl;
    		exit(-1);
    	}
    	p -> front = NULL;
    	p -> end = NULL;
    	cout << "初始化成功!" << endl;
    	return p;
    }
    void pushQueue(HeadNode *hd, Elemtype e) {
    	Queue *p = new Queue;
    	if (p == NULL) {
    		cout << "分配内存失败!请重试!" << endl;
    		exit(-1);
    	}
    	p -> next = NULL;
    	p -> data = e;
    	if(hd -> end != NULL)
            hd -> end -> next = p;
        hd -> end = p;
    	if (hd -> front == NULL) {
    		hd -> front = p;
    	}
    	cout << "入队成功!" << endl;
    }
    void popQueue(HeadNode *hd) {
    	if (isEmpty(hd)) {
    		cout << "该队列为空!不能进行出队操作!" << endl;
    	}
    	Queue *q = hd -> front;
    	Queue *p = q -> next;
    	hd -> front = p;
    	delete q;
    	cout << "出队成功!" << endl;
    }
    Elemtype frontQueue(HeadNode *hd) {
    	if (isEmpty(hd)) {
    		cout << "该队列为空!不能查询队首元素" << endl;
    		return -1;
    	}
    	return hd -> front -> data;
    }
    int main()
    {
    	HeadNode *hd = initQueue();
    	for (int i = 0; i < 10; ++i) {
    		srand(i);
    		Elemtype data = rand() % 100;
    		pushQueue(hd, data);
    		cout << "第 " << i + 1 << " 个元素是 " << data << endl;
    	}
    	cout << "该队列是否为空? " << (isEmpty(hd) ? "True" : "False")  << endl;
    	if (!isEmpty(hd)) {
    		cout << "该队列元素为: " << endl;
    		for (int i = 0; i < 10; ++i) {
    			Elemtype data = frontQueue(hd);
    			cout << "第 " << i + 1 << " 个元素是 " << data << endl;
    			popQueue(hd);
    		}
    	}
    	system("pause");
        return 0;
    }
    

    只写了一些最基本的操作,以后如果可以,再进行添加吧。

    上面的写法是使用链式存储结构,下面是使用顺序存储结构,不多说,还是直接附代码

    因为顺序存储结构的原因,无论是仅让front或是end指针移动,或是将整个表移动,都不是非常合理的方式,所以,用单向循环列表相对来说是最好的方式了。

    /*
    *1.初始化一个队列
    *2.入队
    *3.出队
    *4.获取队首元素
    *5.判断队列是否为空
    *6.判断队列是否为满
    */
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    using namespace std;
    #define MAXN 2000
    
    typedef int Elemtype;
    typedef struct {
    	Elemtype data[MAXN];
    	int front, end;
    }SqQueue;
    /*
    1.front是队首元素的索引。
    2.end是队尾元素的下一个位置的索引
    3.队满的条件是front = end,且front位置的data不为-1
    4.队空的条件是front = end,且front位置的data是-1
    */
    bool isEmpty(SqQueue sq) {
    	if (sq.front == sq.end && sq.data[sq.front] == -1) {
    		return true;
    	} else {
    		return false;
    	}
    }
    bool isFull(SqQueue sq) {
    	if (sq.front == sq.end && sq.data[sq.front] != -1) {
    		return true;
    	} else {
    		return false;
    	}
    }
    SqQueue init(SqQueue sq, int n) {
    	memset(sq.data, -1, sizeof(sq.data));
    	sq.front = 0, sq.end = 0;
    	for (int i = 0; i < n; ++i) {
    		cout << "请输入队列元素:";
    		cin >> sq.data[i];
    		sq.end = (sq.end + 1) % MAXN;
    	}
    	return sq;
    }
    SqQueue push(SqQueue sq, Elemtype elem) {
    	if (isFull(sq)) {
    		cout << "该队列已满!请检查后继续!" << endl;
    		return sq;
    	}
    	sq.data[sq.end] = elem;
    	sq.end = (sq.end + 1) % MAXN;
    	cout << "已将元素 " << elem << " 插入队尾" << endl;
    	return sq;
    }
    SqQueue pop(SqQueue sq) {
    	if (isEmpty(sq)) {
    		cout << "该队列已空!请检查后继续!" << endl;
    		return sq;
    	}
    	sq.data[sq.front] = -1;
    	sq.front = (sq.front + 1) % MAXN;
    	cout << "已将队首元素出队!" << endl;
    	return sq;
    }
    Elemtype front(SqQueue sq) {
    	if (isEmpty(sq)) {
    		cout << "该队列已空!请检查后继续!" << endl;
    		return -1;
    	}
    	return sq.data[sq.front];
    }
    
    int main()
    {
    	SqQueue q;
    	q = init(q, MAXN);
    	q = push(q, 5);
    	q = pop(q);
    	q = push(q, 5);
    	cout << "队列Q的队首元素为: " << front(q) << endl;
        return 0;
    }

    这个数据结构不是很困难,在理解链表的基础上加以限制就好了。对于栈和队列,都是一种受限的线性表。所以如果想学好栈和队列的话还是需要去把链表学好。这里贴一个以前看的一个链表写的不错的。

    http://www.cnblogs.com/wireless-dragon/p/5170565.html

    虽然没有详细的解释链表啊什么的。但是配合着书本以及百度百科,代码等,应该能够对链表有一定得来了解吧。

  • 相关阅读:
    118. Pascal's Triangle
    172. Factorial Trailing Zeroes
    345. Reverse Vowels of a String
    58. Length of Last Word
    383. Ransom Note
    387. First Unique Character in a String
    83. Remove Duplicates from Sorted List
    关于Assembly.CreateInstance()与Activator.CreateInstance()方法
    查看占用指定端口的进程
    如何使用eclipse打开已有工程
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179481.html
Copyright © 2011-2022 走看看