《算法》第一次作业:
Q1: Show the contents of the id[] array and the number of times the array is accessed for each input pair when you use quick-find for the sequence 9-0 3-4 5-8 7-2 2-1 5-7 0-3 4-2.
显示id[]数组的内容,以及对序列9-0 3-4 5-8 7-2 2-1 5-7 0-3 4-2使用快速查找时,每个输入对访问数组的次数;
-
QuickFindUF(10):
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 3 4 5 6 7 8 9 -
union(9, 0):
访问次数:13次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 3 4 5 6 7 8 0 -
union(3, 4):
访问次数:13次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 5 6 7 8 0 -
union(5, 8):
访问次数:13次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 8 6 7 8 0 -
union(7, 2):
访问次数:13次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 8 6 2 8 0 -
union(2, 1):
访问次数:14次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 1 4 4 8 6 1 8 0 -
union(5, 7):
访问次数:14次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 1 4 4 1 6 1 1 0 -
union(0, 3):
访问次数:14次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 4 1 1 4 4 1 6 1 1 4 -
union(4, 2):
访问次数:16次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 1 1 1 1 1 1 6 1 1 1
代码实现:
-
vim quickfind.cc
:#include <iostream> #include <vector> using std::vector; using std::cout; using std::endl; using std::cin; int main() { int n = 0; cin >> n; vector<int> id(n); int i = 0; for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter ) { *iter = i; i++; } int p = 0; int q = 0; while( cin >> p >> q ) { int c = 0; // 记录访问数组次数; int pid = id[p]; c++; int qid = id[q]; c++; cout << "id[] is "; for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter ) { if ( *iter == pid ){ *iter = qid; c++; } c++; cout << *iter; } cout << " and c is" << c << endl; } return 0; }
-
vim quickfind_input.txt
:10 9 0 3 4 5 8 7 2 2 1 5 7 0 3 4 2
-
vim quickfind_output.txt
; -
gcc -l c++ -o quickfind quickfind.cc
; -
./quickfind <quickfind_input.txt >quickfind_output.txt
; -
输出结果:
id[] is 0123456780 and c is 13
id[] is 0124456780 and c is 13
id[] is 0124486780 and c is 13
id[] is 0124486280 and c is 13
id[] is 0114486180 and c is 14
id[] is 0114416110 and c is 14
id[] is 4114416114 and c is 14
id[] is 1111116111 and c is 16
Q2: Do Exercise 1.5.1, but use quick-union (英文教材224页,中文教材141页). In addition, draw the forest of trees represented by the id[] array after each input pair is processed.use quick-union for the sequence 9-0 3-4 5-8 7-2 2-1 5-7 0-3 4-2.
依附根节点,左根连右根;
访问次数 = p查找根的次数 + q查找根的次数 + 1(将根连到一起);
-
QuickUnionUF(10):
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 3 4 5 6 7 8 9 -
union(9, 0):
访问次数:1 + 1 + 1 = 3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 3 4 5 6 7 8 0 -
union(3, 4):
访问次数:1 + 1 + 1 = 3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 5 6 7 8 0 -
union(5, 8):
访问次数:1 + 1 + 1 = 3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 8 6 7 8 0 -
union(7, 2):
访问次数:1 + 1 + 1 = 3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 4 4 8 6 2 8 0 -
union(2, 1):
访问次数:1 + 1 + 1 = 3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 1 4 4 8 6 2 8 0 -
union(5, 7):
访问次数:2 + 3 + 1 = 6次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 1 4 4 8 6 2 1 0 -
union(0, 3):
访问次数:1 + 2 + 1 = 4次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 4 1 1 4 4 8 6 2 1 0 -
union(4, 2):
访问次数:1 + 2 + 1 = 4次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 4 1 1 4 1 8 6 2 1 0
代码实现:
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::cin;
int main()
{
int n = 0;
cin >> n;
vector<int> id(n);
int i = 0;
for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter )
{
*iter = i;
i++;
}
int p = 0;
int q = 0;
while( cin >> p >> q ) {
int c = 0; // 记录数组访问次数;
//如果p或q位置存的不是自己的标号,说明自己不是父节点,向上追溯;
int k = 0;
while ( ( k = id[p] ) != p ){
p = k;
c++;
}
c++; // 虽然判断相等,没有进入循环,但是还是对数组进行了一次访问;
while ( ( k = id[q] ) != q ){
q = k;
c++;
}
c++;
id[p] = q; // p的根连到q的根上;
c++;
cout << "id[] is ";
for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter )
{
cout << *iter;
}
cout << " and c is " << c << endl;
}
return 0;
}
输出:
id[] is 0123456780 and c is 3
id[] is 0124456780 and c is 3
id[] is 0124486780 and c is 3
id[] is 0124486280 and c is 3
id[] is 0114486280 and c is 3
id[] is 0114486210 and c is 6
id[] is 4114486210 and c is 4
id[] is 4114186210 and c is 4
Q3:Do Exercise 1.5.1, but use weighted quick-union,use weighted quick-union for the sequence 9-0 3-4 5-8 7-2 2-1 5-7 0-3 4-2.
-
QuickWeightUnionUF(10):
[] 0 1 2 3 4 5 6 7 8 9 id[] 0 1 2 3 4 5 6 7 8 9 sz[] 1 1 1 1 1 1 1 1 1 1 -
union(9, 0):
访问id[]次数:3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 1 2 3 4 5 6 7 8 9 sz[] 1 1 1 1 1 1 1 1 1 2 -
union(3, 4):
访问id[]次数:3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 1 2 3 3 5 6 7 8 9 sz[] 1 1 1 2 1 1 1 1 1 2 -
union(5, 8):
访问id[]次数:3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 1 2 3 3 5 6 7 5 9 sz[] 1 1 1 2 1 2 1 1 1 2 -
union(7, 2):
访问id[]次数:3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 1 7 3 3 5 6 7 5 9 sz[] 1 1 1 2 1 2 1 2 1 2 -
union(2, 1):
访问id[]次数:4次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 7 7 3 3 5 6 7 5 9 sz[] 1 1 1 2 1 2 1 3 1 2 -
union(5, 7):
访问id[]次数:3次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 7 7 3 3 7 6 7 5 9 sz[] 1 1 1 2 1 2 1 5 1 2 -
union(0, 3):
访问id[]次数:4次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 7 7 9 3 7 6 7 5 9 sz[] 1 1 1 2 1 2 1 5 1 4 -
union(4, 2):
访问id[]次数:6次;
[] 0 1 2 3 4 5 6 7 8 9 id[] 9 7 7 9 3 7 6 7 5 7 sz[] 1 1 1 2 1 2 1 9 1 4
代码实现:
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::cin;
int main()
{
int n = 0;
cin >> n;
vector<int> id(n);
vector<int> sz(n, 1); // 初始权重数组的初始权重为1;
int i = 0;
for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter )
{
*iter = i;
i++;
}
int p = 0;
int q = 0;
while( cin >> p >> q ) {
int idc = 0; //对id数组的访问次数;
int szc = 0; //对sz数组的访问次数;
while ( id[p] != p ){
p = id[p];
idc++;
}
idc++;
while ( id[q] != q ){
q = id[q];
idc++;
}
idc++;
// 前面的查找根和quickunion相同,但是合并根要根据sz数组的值;
// if ( sz[p] <= sz[q] ){ id[p] = q; sz[q] += sz[p]; }
int szp, szq;
if ( (szp = sz[p]) < (szq = sz[q]) ){
id[p] = q;
sz[q] += szp;
idc++;
szc += 3;
}
else {
id[q] = p;
sz[p] += szq;
idc++;
szc += 3; //访问sz数组两次,赋值sz数组一次,一共三次;
}
cout << "id[] is ";
for ( vector<int>::iterator iter = id.begin(); iter != id.end(); ++iter )
{
cout << *iter;
}
cout << "; sz[] is ";
for ( int i = 0; i != n; ++i)
{
cout << sz[i];
}
cout << "; idc is " << idc << "; szc is " << szc << endl;
}
return 0;
}
结果:
id[] is 9123456789; sz[] is 1111111112; idc is 3; szc is 3
id[] is 9123356789; sz[] is 1112111112; idc is 3; szc is 3
id[] is 9123356759; sz[] is 1112121112; idc is 3; szc is 3
id[] is 9173356759; sz[] is 1112121212; idc is 3; szc is 3
id[] is 9773356759; sz[] is 1112121312; idc is 4; szc is 3
id[] is 9773376759; sz[] is 1112121512; idc is 3; szc is 3
id[] is 9779376759; sz[] is 1112121514; idc is 4; szc is 3
id[] is 9779376757; sz[] is 1112121914; idc is 6; szc is 3