数据结构_第二周编程作业_C++题解

DS_Lecture 2 Assignments_C++题解

中国大学MOOC_陈越、何钦铭_数据结构_第二周编程作业

1. 两个有序链表序列的合并

C语言函数填空题,训练最基本的链表操作。会C编程=》必做

List Merge( List L1, List L2 )
{
    List L;
    PtrToNode rear;
    L = (List)malloc(sizeof(struct Node));
    rear = L;
    while(L1->Next&&L2->Next){
		if (L1->Next->Data <= L2->Next->Data){
			rear->Next = L1->Next;
			L1->Next = L1->Next->Next;
			rear = rear->Next;
		}
		else{
			rear->Next = L2->Next;
			L2->Next = L2->Next->Next;
			rear = rear->Next;
		}
    }
    for (;L1->Next;L1->Next = L1->Next->Next){
    	rear->Next = L1->Next;
		rear = rear->Next;
	}
    for (;L2->Next;L2->Next = L2->Next->Next){
    	rear->Next = L2->Next;
		rear = rear->Next;
	}
    return L;
}

2. 一元多项式的乘法与加法运算

“小白专场”中详细讨论了C语言实现的方法。不会C=》必做

#include<cstdio>
#include<cstdlib>
using namespace std;

struct PolyNode {
	int coef;
	int expon;
	PolyNode* link;
};
typedef PolyNode* Polynomial;

void Attach(int c, int e, Polynomial* prear)
{
	PolyNode* node = new PolyNode();
	node->coef = c;
	node->expon = e;
	(*prear)->link = node;
	*prear = node;
}

Polynomial ReadPoly()
{
	int N, c, e;
	scanf("%d",&N);
	Polynomial p, rear, temp;
	p = new PolyNode();
	rear = p;
	for (int i = 0; i < N; i++){
		scanf("%d%d", &c, &e);
		Attach(c,e,&rear);
	}
	temp = p; p = p->link; free(temp);
	return p;
}

Polynomial Mult(Polynomial p1, Polynomial p2)
{
	if (!p1||!p2) return NULL;
	
	Polynomial p, rear, t1, t2, temp;
	p = new PolyNode();
	rear = p;
	t1 = p1; t2 = p2;
	int c, e;
	while (t2){
		c = t1->coef * t2->coef;
		e = t1->expon + t2->expon;
		Attach(c, e, &rear);
		t2 = t2->link;
	}	
	t1 = t1->link;
	while (t1){
		t2 = p2; rear = p;
		while (t2){
			c = t1->coef * t2->coef;
			e = t1->expon + t2->expon;
			while (rear->link && rear->link->expon > e){
				rear = rear->link;
			}
			if (rear->link && rear->link->expon == e){
				if (rear->link->coef + c){
					rear->link->coef += c;
				}
				else{
					Polynomial temp = rear->link;
					rear->link = temp->link;
					free(temp);
				}
			}
			else{
				PolyNode* node = new PolyNode();
				node->coef = c;
				node->expon = e;
				node->link = rear->link;
				rear->link = node;
				rear = rear->link;
			}
			t2 = t2->link;
		}
		t1 = t1->link; 
	}
	temp = p; p = p->link; free(temp);
	return p;
}

Polynomial Add(Polynomial p1, Polynomial p2)
{
	Polynomial p, rear, t1, t2, temp;
	p = new PolyNode();
	rear = p;
	t1 = p1; t2 = p2;
	while (t1 && t2){
		if (t1->expon == t2->expon){
			if (t1->coef + t2->coef != 0) Attach(t1->coef + t2->coef, t1->expon, &rear);
			t1 = t1->link;
			t2 = t2->link;
		}
		else if(t1->expon > t2->expon){
			Attach(t1->coef, t1->expon, &rear);
			t1 = t1->link;
		}
		else{
			Attach(t2->coef, t2->expon, &rear);
			t2 = t2->link;
		}
	}
	for (; t1; t1 = t1->link) Attach(t1->coef, t1->expon, &rear);
	for (; t2; t2 = t2->link) Attach(t2->coef, t2->expon, &rear);
	temp = p; p = p->link; free(temp);
	return p;
}

void PrintPoly(Polynomial p)
{
	if (!p){
		printf("0 0\n");
		return;
	}
	int flag = 0;
	while (p){
		if (!flag) flag = 1;
		else printf(" ");
		printf("%d %d", p->coef, p->expon);
		p = p->link;
	}
	printf("\n");
}

int main()
{
	Polynomial p1, p2, pm, ps;
	p1 = ReadPoly();
	p2 = ReadPoly();
	pm = Mult(p1, p2);
	PrintPoly(pm);
	ps = Add(p1, p2);
	PrintPoly(ps);
}

链表使用结构体,结构体初始化可以像c语言那样使用malloc,也可以使用new关键词,返回这个结构体的指针

  • c malloc: PolyNode* node = (PolyNode*)malloc(sizeof(struct PolyNode)); node->link = NULL;
  • c++ new: PolyNode* node = new PolyNode; node->link = NULL; 指针变量值是随机的
  • c++ new(): PolyNode* node = new PolyNode(); 指针变量值初始为null

3. PAT(A) 1074 Reversing Linked List

  • 根据某大公司笔试题改编的2014年春季PAT真题,不难,可以尝试;
  • ↑ 老师说的不难和我认为的不难不是一个不难,写了好久最后还是参考了小姐姐的代码,发现自己思路完全跑偏orz
#include<iostream>
#define MAXSIZE 100000
using namespace std;
int main()
{
	int first, N, K;
	cin >> first >> N >> K;
	int address, data[MAXSIZE], next[MAXSIZE];
	for (int i = 0; i < N; i++){
		cin >> address;
		cin >> data[address] >> next[address];
	}
	int sum = 0;
	int *list = new int[N];
	while(first != -1){
		list[sum++] = first;
		first = next[first];
	}
	int *result = new int[sum];
	for (int i = 0; i < sum - sum % K; i++){
		result[i] = list[i / K * K + K - 1 - i % K];
	}
	for (int i = sum - sum % K; i < sum; i++){
		result[i] = list[i];
	}
	for (int i = 0; i < sum - 1; i++){
		printf("%05d %d %05d\n", result[i], data[result[i]], result[i+1]);
	}
	printf("%05d %d %d\n", result[sum-1], data[result[sum-1]], -1);
	return 0;
}

思路:

输入数据有地址和对应数据,限制最多10^5个结点,开两个最大量数组,初始数据按地址分别存入,后面可以直接利用地址到数组中索引得到内容。将结点连接成链表,将地址按正确的顺序依次存入list,用sum记录连入链表的结点数。按反转的顺序将地址读入result中,以result的顺序依次读取对应地址的数据。

4. PAT(A) 1051 Pop Sequence

2013年春季PAT真题,考察队堆栈的基本概念的掌握,可以尝试。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
	int m, n, k, old, cur;
	cin >> m >> n >> k;
	vector<int> pop;
	int *seq = new int[n];
	for (int i = 0; i < k; i++){
		bool flag = true;
		for (int j = 0; j < n; j++){
			cin >> seq[j];
		}
		old = 0;
		for (int j = 0; j < n; j++){
			cur = seq[j];
			if (cur > m + pop.size()){
				flag = false;
				break;
			}
			else if (cur >= old - 1){
				pop.push_back(cur);
				old = cur;
			}
			else{
				for (int sub = 1; sub < old - cur; sub++){
					auto it = find(pop.begin(), pop.end(), cur + sub);
					if (it == pop.end()){
						flag = false;
						break;
					}
				}
				if (!flag) break;
				pop.push_back(cur);
				old = cur;
			}
		}
		if (!flag) cout << "NO\n";
		else cout << "YES\n";
		pop.clear();
	}
}

思路:

  • 用一个vector记录已经弹出的元素,每进行一个新的串的检查后要清空。
  • cur > m + pop.size()说明现有栈容量不足以容纳直到cur的元素
  • cur < old - 1说明不是连续弹出,要检查cur,old之间的元素是否都已经弹出
  • 参考小姐姐的代码
posted @ 2019-05-10 11:05  鲸90830  阅读(298)  评论(0)    收藏  举报