第一题
链表类这个题目其实思想上并不难,只是有些细节需要注意:
- 节点的定义中指针的初始化。这个再强调一次,如果你的类中涉及到new某个结构,那么在对应指针变量定义的时候注意初始化给它赋值为nullptr,这是一个好习惯,因为在后续涉及delete的时候,这种操作会避免delete一片系统赋予的空间从而报错。
- 头结点。链表最好是写一个头结点,因为这样可以统一空表和普通的链表,一方面代码可以少写一点,另一方面在思考上不必去额外分析,既是给自己方便也是给读代码的人方便。
剩下的就没啥太多问题了,关键的函数老师上课也讲述过相应的知识点
#include<iostream>
using namespace std;
struct ListNode
{
int val;
ListNode* next = nullptr;
ListNode(int in = 0):val(in){};
};
class MyLinkedList {
public:
MyLinkedList() {
this->size = 0;
this->head = new ListNode(0);
}
int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
ListNode *cur = head;
for (int i = 0; i <= index; i++) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
addAtIndex(0, val);
}
void addAtTail(int val) {
addAtIndex(size, val);
}
void addAtIndex(int index, int val) {
if (index > size) {
return;
}
index = max(0, index);
size++;
ListNode *pred = head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
ListNode *toAdd = new ListNode(val);
toAdd->next = pred->next;
pred->next = toAdd;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
ListNode *pred = head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
ListNode *p = pred->next;
pred->next = pred->next->next;
delete p;
}
void printf()
{
ListNode *cur =head ->next;
while(cur != NULL)
{
cout <<cur->val<<" ";
cur = cur -> next;
}
}
~MyLinkedList()
{
ListNode *tmp,*cur =head ->next;
while(cur != NULL)
{
tmp = cur;
cur = cur -> next;
delete tmp;
}
delete head;
}
private:
int size;
ListNode *head;
};
第二题
二叉树这个地方是给大家自由发挥来着,其实主要就是一种面向对象的思想,二叉树的一个节点需要哪些属性呢?无非就是三个,节点的val,指向左子树的指针和指向右子树的指针。结构确定好之后就是想办法去实现对应的函数,先序遍历那三个之前的题目也有过,实际上比较简单的思路就是直接递归,小改一下位置就能实现不同的遍历,主要是层序。这块涉及到队列的知识,可以看看这个博客C++队列。基础的算法思路就是:
- 头结点入队
- 取出队头元素,遍历之后将非空左右子节点入队
- 重复2直到队列为空
实际上后面如果学了BFS你们就会发现这个也可以用来作为BFS的数据存储结构,稍微变通一下即可
main.cpp如下
#include<iostream >
#include"class.h"
using namespace std;
int main ()
{
BinaryTree tree;
int n;
cin >>n;
int arr[n+1];
for(int i=1;i<=n;i++)
cin>>arr[i];
tree.trans(arr,n,1,tree.root);
tree.PreOrderTraverse(tree.root);
cout <<endl;
tree.MidOrderTraverse(tree.root);
cout <<endl;
tree.EndOrderTraverse(tree.root);
cout <<endl;
tree.LevelOrderTraverse();
cout <<endl;
}
二叉树类如下:
#ifndef CLASS_H
#define CLASS_H
#include<iostream>
using namespace std;
struct BitNode {
/* data */
int data;
BitNode* lchild;
BitNode* rchild;
BitNode(int in=0) : data(in), lchild(nullptr), rchild(nullptr) {};
};
class BinaryTree {
private:
int count;
public:
BitNode *root;
BinaryTree() : root(nullptr),count(0){};
void trans(int *arr,int total, int index, BitNode *& current)
{
if(index > total)
return;
else
{
int x=arr[index];
if(x != -1)
{
count++;
current = new BitNode(x);
trans(arr, total, 2 * index, current -> lchild);
trans(arr, total, 2 * index + 1, current -> rchild);
}
else
current = nullptr;
}
}
void PreOrderTraverse(BitNode*& node ) {
if (node) {
cout << node ->data<<" ";
PreOrderTraverse(node -> lchild);
PreOrderTraverse(node -> rchild);
}
}
void MidOrderTraverse(BitNode*& node ) {
if (node) {
MidOrderTraverse(node -> lchild);
cout << node ->data<<" ";
MidOrderTraverse(node -> rchild);
}
}
void EndOrderTraverse(BitNode*& node ) {
if (node) {
EndOrderTraverse(node -> lchild);
EndOrderTraverse(node -> rchild);
cout << node ->data<<" ";
}
}
void LevelOrderTraverse()
{
BitNode* all[2*count];
BitNode* cur;
int l=0,r=0;
all[r++]=root;
while(l<r)
{
cur = all[l++];
cout << cur->data <<" ";
if(cur->lchild)
all[r++]=cur->lchild;
if(cur->rchild)
all[r++]=cur->rchild;
}
}
};
#endif