数据结构课后作业
第一章
1. 求下列语句段的时间复杂度
(1)
for ( i=1; i<n; i++ )
for ( j=1; j<= i; j++ )
x++;
解:
(2)
i = 1;
while (i < n)
i = i*2;
(3)
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
for (k=1; k<=n; k++)
x++;
(4)
for (i=1; i<n; i++)
for (j=1; j<n; j++)
x++;
for (k=1; k<n; k++)
x++;
2.编写算法以计算在给定各系数和变量x的值时的多项式 f n ( x ) f_n(x) fn(x)的值,要求时间尽可能少
(提示:可将各系数存储在数组A中;另外,乘法运算的时间是加法运算时间的数倍)
f
n
(
x
)
=
a
n
x
n
+
a
(
n
−
1
)
x
(
n
−
1
)
+
a
(
n
−
2
)
x
(
n
−
2
)
+
…
.
.
a
2
x
2
+
a
1
x
+
a
0
\ f_n(x)= a_nx^n +a_(n-1)x^(n-1)+a_(n-2)x^(n-2)+….. a_2x^2+a_1x+a_0
fn(x)=anxn+a(n−1)x(n−1)+a(n−2)x(n−2)+…..a2x2+a1x+a0
解答:
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> coef;
int i = 0;
int x;
cout << "请输入a0至an:" << endl;
do {
cin >> i;
coef.push_back(i);
} while (getchar() != '\n');
int val = coef[coef.size() - 1];
cout << "请输入x的值:" << endl;
cin >> x;
for (int i = coef.size() - 1; i > 0; i--) {
val = val * x + coef[i - 1];
}
cout << "多项式值为:" << val << endl;
return 0;
}
3.设计算法求集合{1, 2, …, n}的幂集
解答:
#include<iostream>
using namespace std;
int main(){
int n; cin >> n;
for (int i = 0; i < (1 << n); i++) {
cout << "{";
for (int j = 0; j < n; j++) {
if (i & (1 << j))
cout << j+1 << " ";
}
cout << "}" << endl;
}
return 0;
}
4.设计算法将整型数组A[n]中的元素调整为左右两部分,其中左边所有元素为奇数,右边所有元素为偶数。并要求算法的时间复杂度为O(n)
解答:
#include<iostream>
#include<vector>
using namespace std;
int main(){
int i = 0;
vector<int>A;
do {
cin >> i;
A.push_back(i);
} while (getchar() != '\n');
int l=0, r=A.size()-1;
while (l < r) {
while (A[l] % 2 != 0) {
l++;
}
while (A[r] % 2 == 0) {
r--;
}
swap(A[l], A[r]);
l++;
r--;
}
for (auto item : A) {
cout << item << " ";
}
return 0;
}
5.已知输入序列中各元素的值至少有两个元素。设计算法求出该序列中元素的所有最大升、降子序列。
例如:若元素依次为(1,20,30,12,3,5,7,4,6,100,11,8),则输出结果为(1,20,30),(30,12,3),(3,5,7),(7,4),(4,6,100),(100,11,8)
解答:
#include<iostream>
#include<vector>
using namespace std;
void print(int slow, int fast, vector<int> s) {
for (int i = slow; i <= fast; i++) {
cout << s[i] << " ";
}
cout << endl;
}
int main()
{
int n;
cin >> n;
vector<int> s(n);
int slow, fast;
for (int i = 0; i < n; i++) {
cin >> s[i];
}
slow = 0;
fast = 1;
for (; slow < n-1; slow = fast-1) {
while ((s[slow + 1] - s[slow]) * (s[fast] - s[fast - 1]) > 0) {
fast++;
}
print(slow, fast-1, s);
}
return 0;
}
6.背包问题:设有n个物品,其重量分别为w1,w2,w3,…,wn,所有物品的重量之和≥背包所能放置的重量S。设计算法从中找出若干物品放入背包中,使得其重量之和正好为S
例如,S = 50, n = 10, w = ( 29 26 18 16 13 10 8 5 3 1)
解答:
#include<iostream>
#include<vector>
using namespace std;
void fillPackage(int s,int n,vector<int>w,int begin, vector<vector<int>>& res,vector<int> comb) {
if (s == 0) res.push_back(comb);
for (int i = begin; i < n; i++) {
comb[i]=1;
fillPackage(s - w[i], n, w, i + 1, res,comb);
comb[i]=0;
}
}
int main(){
int n = 10;
int s = 50;
vector<int>w = { 29,26,18,16,13,10,8,5,3,1 };
vector<vector<int>> res;
vector<int> comb(n, 0);
fillPackage(s, n, w, 0, res,comb);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res[i].size(); j++) {
if (res[i][j] == 1) {
cout << "(" << j+1 << "," << w[j] << ")";
}
}
cout << endl;
}
return 0;
}
第二章
1.对一个栈的输入序列a1, a2, a3, …, an,称由此栈依次出栈后所得到的元素序列为栈的合法输出序列
例如: 假设栈S的一个输入序列为1, 2, 3, 4, 5,则可得到多个输出序列,如1, 2, 3, 4, 5就是一个合法的输出序列,同理, 5, 4, 3, 2, 1和3, 2, 1, 4, 5也分别是其合法的输出序列。分别求解下列问题:
(1)判断序列1, 3, 4, 5, 2是否是合法的输出序列;
解答:
是
(2)对输入序列1, 2, 3, 4, 5,求出其所有的合法的输出序列;
解答:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
void to_s(queue<int>input, stack<int>s, queue<int>output);
void out_s(queue<int>input, stack<int>s, queue<int>output);
void valid_output(queue<int>input, stack<int>s, queue<int>output);
void to_s(queue<int>input, stack<int>s, queue<int>output)
{
if (input.empty())
return;
s.push(input.front());
input.pop();
valid_output(input, s, output);
}
void out_s(queue<int>input, stack<int>s, queue<int>output)
{
if (s.empty())
return;
output.push(s.top());
s.pop();
valid_output(input, s, output);
}
void valid_output(queue<int>input, stack<int>s, queue<int>output)
{
if (input.empty() && s.empty())
{
while (!output.empty())
{
cout << output.front()<<" ";
output.pop();
}
cout << endl;
return;
}
to_s(input, s, output);
out_s(input, s, output);
}
int main()
{
queue<int> input;
stack<int> s;
queue<int> output;
cout << "请输入序列:";
int i = 0;
do {
cin >> i;
input.push(i);
} while (getchar() != '\n');
cout << "合法的输出序列有:" << endl;
valid_output(input, s, output);
return 0;
}
(3)设计算法以判断对输入序列1, 2, 3, …, n,序列a1, a2, a3,
…, an是否是该栈的合法的输出序列(假设输出序列在数组A中);
解答:
#include<iostream>
#include<vector>
using namespace std;
int isValid(vector<int>A) {
for (int i = 0; i < A.size(); i++) {
int low = A[i];
for (int j = i + 1; j < A.size(); j++) {
if (A[j] < A[i]) {
if (A[j] > low) return false;
else low = A[j];
}
}
}
return true;
}
int main(){
int i = 0;
vector<int>A;
do {
cin >> i;
A.push_back(i);
} while (getchar() != '\n');
if (isValid(A)) cout << "该序列合法" << endl;
else cout << "该序列不合法" << endl;
return 0;
}
(4)给出栈的合法的输出序列的规律。
解答:
对于第i个数,在其后面的比其小的数,必须是降序排列。
2.如果顺序栈中的第二个分量是栈顶指针top而不是记录元素个数的变量count,应如何实现各算法?
解答:
初始化函数的实现:
Stack::Stack() {
top = 0;
}
判断空的函数的实现:
Bool Stack::Empty() const{
if ( top == 0 ) return TRUE;
else return FALSE;
}
判断满的函数的实现:
Bool Stack::full() const{
if ( top == maxlen ) return TRUE;
else return FALSE;
}
取栈顶元素的实现:
error_code Stack::Get_top(elemenType &x) const{
if ( empty() ) return underflow;
else {
x = data[--top];
}
return success;
}
入栈的实现:
error_code Stack::Push (const elemenType x){
if ( full() ) return overflow;
data[top++] = x;
return success;
}
出栈的实现:
error_code Stack::Pop() {
if ( empty() ) return underflow;
top --;
return success;
}
3.对一个合法的数学表达式来说,其中的各大小括号“{”,“}”,“[”,“]”,“(”和“)”应是相互匹配的。设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的?
解答:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
bool isValid(string s) {
if (s.size() % 2 != 0) return false;
stack<char> st;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '{') st.push('}');
else if (s[i] == '(') st.push(')');
else if (s[i] == '[') st.push(']');
else if (st.empty() || s[i] != st.top()) return false;
else st.pop();
}
return st.empty();
}
int main() {
string s;
cin >> s;
if (isValid(s)) cout << "括号匹配" << endl;
else cout << "括号不匹配" << endl;
return 0;
}