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

数据结构学习笔记--队列

2016-10-07 00:32 423 查看
队列

【引出队列】引子非常长~~~请耐心看

问题背景:

求杨辉三角形的第K层的所有元素的值。

问题抽象:

输入:一个数字K

输出项:K个数字

处理过程:如果我们要求第K层第I个数字时,我们需要先求Y[K-1,I-1] 和Y[K-1,I]的值。这个问题需要一层层往上,所以变成了一个递归。

第一种方案:递归思想
int32_t solve_one(int32_t k, int32_t i)
{
if (i <= 0 || k <= 0 || i > k) return 0;
if (i == 1 || k == i) return 1;
return solve_one(k - 1, i - 1)+solve_one(k - 1, i);
}

int main(int argc, char* argv[])
{
int32_t k, process_i;
int32_t begin;
process_i = 1;
while (cin >> k)
{
begin = clock();
switch (process_i) {
case 1:
cout << "process 1 :";
for (int32_t i = 1; i <= k; i++)
{
cout << solve_one(k, i) << "  ";
}
cout << endl;
break;

default :
break;
}
cout << (clock() - begin) / 1000 << " ms" << endl;
}
return 0;
}
数据结果:



实验结果发现,随着层数越来越多的时候,它的时间与层数是2倍的往上涨。明显这个算法的复杂度过高。主要是因为我们会重复求解上一层的结果。

解决方案二:记录所有已经计算的结果。

const int32_t MAX_K = 1000;

int32_t Y_NUMS[MAX_K][MAX_K] = { 0 };

int32_t solve_one_2(int32_t k, int32_t i)
{
if (i <= 0 || k <= 0 || i > k) return 0;
if (i == 1 || k == i) return 1;
if (Y_NUMS[k][i] == 0) return Y_NUMS[k][i] = solve_one_2(k - 1, i - 1) + solve_one_2(k - 1, i);
return Y_NUMS[k][i];
}




我们发现时间已经特别好了。但是又个问题,就是空间问题。我们会发现这个问题需要一个MAX_K*MAX_K的数组矩阵放在内存。这是一个比较笨的方法。

解决方案三:我们只储存K-1行的数据,用来计算K层

bool solve_one_3(int32_t k, int32_t y_nums[2][MAX_K])
{
if (k <= 0) return false;
for (int32_t i = 0; i <= k; i++)
{
y_nums[i % 2][1] = 1;
y_nums[i % 2][i] = 1;
for (int32_t j = 2; j <= i - 1; j++)
{
y_nums[i % 2][j] = y_nums[(i - 1) % 2][j - 1] + y_nums[(i - 1) % 2][j];
}
}
return true;
}

int main(int argc, char* argv[])
{
int32_t k, process_i;
int32_t begin;
int32_t y_nums[2][MAX_K];
cin>>process_i ;
while (cin >> k)
{
begin = clock();
switch (process_i) {
case 1:
cout << "process 1 :";
for (int32_t i = 1; i <= k; i++)
{
cout << solve_one(k, i) << "  ";
}
cout << endl;
break;
case 2:
cout << "process 2 :";
for (int32_t i = 1; i <= k; i++)
{
cout << solve_one_2(k, i) << "  ";
}
cout << endl;
break;
case 3:
cout << "process 3 :";
solve_one_3(k, y_nums);
for (int32_t i = 1; i <= k; i++)
{
cout << y_nums[k%2][i] << "  ";
}
cout << endl;
break;
default :
break;
}
cout << (clock() - begin) / 1000 << " ms" << endl;
}
return 0;
}



我们会发现从上至下的思维方式,可以让空间和时间都会非常少。这其实这是一个有先后顺序的事件,通常有先进先出的性质。所以我们就需要有队列。

【队列介绍】

队列是一种先进先出的数据结构,可以用来处理时间之间具有先后关系的问题。

- 有一个指针head,指向队列首部(有元素的位置)。

- 有一个指针tail,指向队列尾部(一个空位置)

- 当head==tail时,队列为空

- Head+1即将队首元素移动了1个位置

- 新进的元素放在tail所指向的位置,然后tail+1

队列有以下几个过程:

1、 初始化

2、 问题求解

3、 新问题发现

4、 问题出队,判空(如果非空转2,空则转5)

5、 结束

用队列完成杨辉三角的代码

bool solve_one_4(int32_t k,int32_t y_nums[2][MAX_K])
{
if (k <= 0) return false;
queue<event> temp_queue;
event e1, e2;
int32_t l, p;
e1.l = 1,e1.p = 1;
temp_queue.push(e1);
while(!temp_queue.empty())
{
e1 = temp_queue.front();
l = e1.l, p = e1.p;
if (p == 1 || p == l) {
y_nums[l % 2][p] = 1;
}
else
{
y_nums[l % 2][p] = y_nums[(l - 1) % 2][p - 1] + y_nums[(l - 1) % 2][p];
}
if (l != k)
{
e2.l = l + 1;
e2.p = p;
temp_queue.push(e2);
if (p == l) {
e2.p = p + 1;
temp_queue.push(e2);
}
}
temp_queue.pop();
}
return true;
}


参考:

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