hello-algo 链表 队列 栈 数组 二叉树等数据结构再学习

#include<iostream>
#include<vector>
#include<deque>//是双端队列
#include <queue> // 队列头文件
using namespace std;
		
//链表
class  ListNode
{
private:
	int val;

public:
	ListNode* next;
	ListNode(int x) :val(x), next(nullptr) {};
	void insert(ListNode* n0, ListNode* p);
	void delte(ListNode* n0);
	
	int getval()const {
		return val;
	}

	ListNode* access(ListNode* head, int index)//返回第i个节点的值
	{
		for (int i = 0; i < index; i++)
		{
			if (head == nullptr)return nullptr;
			head = head->next;
		}
		return head;
	}
	//返回链表里==target的 index
	int find(ListNode* head, int target) {
		int index = 0;
		while (head != nullptr) {
			if (head->getval() == target)
			{
				return index;
			}
			head = head->next;
			index++;
		}
		return -1;
	}
	//从头节点插入链表节点
	//插入前:
	//n0 → n1 → n2 → ...
	//执行过程:
	//1. 记住n0的下一个(n1)
	//2. 让p指向n1
	//3. 让n0指向p
	//
	//插入后:
	//n0 → p → n1 → n2 → ...
	void insert(ListNode* n0, ListNode* p)
	{
		ListNode* n1 = n0->next;
		p->next = n1;
		n0->next = p;
	}

	//删除n0后面的那个节点(记为p)
	void delete_node(ListNode* n0)
	{
		if (n0->next == nullptr) return;

		ListNode* p = n0->next;   //n0->p->n1;
		ListNode* n1 = p->next;
		n0->next = n1;

		delete p;
	}

	//head-1-2-3-4-null
	//对的理解:: 1-null curr原来是1-5表示一整条,现在被打断了 cur =1-null
	//next =2-3-4-5-null
	//1.next=null;
	//prev = 1 - null;
	//cur=2-3-4-5-null 
	// 第二次循环: next =3-4-5-null  curr-next=1-null curr变成 2-1-null
	// prev=2-1-null
	// curr=3-4-5-null
	// 第三次循环
	// next=4-5-null curr=3
	// 3.next=2-1-null;  curr 变成3-2-1-null
	// prev=3-2-1-null
	// curr= 4-5-null
	// 第四次 next=5-null
	// 4.next=3-2-1-null
	// prev=4-3-2-1-null
	// curr =5-null
	// 第五次 next=null
	// 5.next=4-3-2-1-null
	// prev=5-4-3-2-1-null
	// curr=null
	static ListNode* re_new(ListNode* head)
	{
		ListNode* cur = head;
		ListNode* prev = nullptr;

		while (cur != nullptr)
		{
			ListNode* next = cur->next;//保存下一个指针,后续一大串这个时候保存
			cur->next = prev;//打断cur
			prev = cur;//保存倒叙链表
			cur = next;//更新cur给下一次循环
		}
		return prev;
	}
	//static ListNode* reverse(ListNode* head) {
	//	ListNode* prev = nullptr;
	//	ListNode* curr = head;
	//	while (curr != nullptr) {
	//		ListNode* next = curr->next;  // 保存下一个节点以及后面的节点
	//		curr->next = prev;            // 反转指针  
	//		prev = curr;                  // 前移prev  
	//		curr = next;                  // 前移curr  
	//	}

	//	return prev;  // 返回新的头节点
	//}

	//递归理解
	/*1 - 2 - 3 - 4 - 5 - null
		head->next->next = head会让后面的节点指回当前节点,形成短暂的双向环。
		head->next = nullptr立刻断开当前节点向后的指针,打破环。

		head = 4 的循环 内:返回的newhead = 5
		head - n - n = 4 - 5 - null = 4 - 5 - 4 = 4 < ->5成环
		head.next = null  4 - null :5 - 4 - null 头节点不可能下个为空
		返回newhead = 5
		head = 3的循环内: 	newhead = 5
		3 - 4 - 5 = head = 3 < ->4 成环
		3.next = null :5 - 4 - 3 - null
		返回newhead = 5
		head = 2    	          :    	newhead = 5
		2 - 3 - 4 : 2 < ->3 成环
		2.next = null  5 - 4 - 3 - 2 - null
		返回 5
		head = 1             : newhead = 5
		1 - 2 - 3: 1 < ->2成环
		1.next = null 5 - 4 - 3 - 2 - 1 - null
		返回5*/

	//static ListNode* digui_revrse(ListNode* head)
	//{
	//	if (head->next == nullptr || head == nullptr)
	//	{
	//		return head;
	//	}

	//	ListNode* newhead = digui_revrse(head->next);
	//	head->next->next = head;
	//	head->next = nullptr;
	//	return newhead;

	

	// 递归反转
	static ListNode* reverseRecursive(ListNode* head) {
		if (head == nullptr || head->next == nullptr) {
			return head;
		} //递归终止条件
		ListNode* newHead = reverseRecursive(head->next); 
		head->next->next = head;  // 反转指向             
		head->next = nullptr;      // 原头节点变为尾节点  
		                                                  
		return newHead;                                   
	}														
};


//栈 特性是先进后出,叠盘子,被拿走的是最上面的
//栈的链表实现
class linkedliststack {
private:
	ListNode* stackTop;
	int stksize;
public:
	linkedliststack() {
		stackTop = nullptr;
		stksize = 0;
	}

	//~linkedliststack() {
	//	freememorylinkerlist(stackTop);
	//}

	int size() {
		return stksize;
	}

	bool isempty()
	{
		return size() == 0;
	}

	//入栈
	void push(int num)
	{
		//在链表头节点添加节点
		ListNode* node = new ListNode(num);//new一个新的节点 存入的是要栈的头节点
		node->next = stackTop;
		stackTop = node;//转换指针指向
		stksize++;
	}

	//取出头栈值
	int top() {
		if (isempty) {
			throw out_of_range("索引越界");
		}
		return stackTop->getval();
	}

	//出栈

	//int pop() {

	//	int num = top();//取出头节点值
	//	ListNode* tmp = stackTop;//取出栈顶指针
	//	tmp = tmp->next;

	//	return num;
	//}

	int pop() {
		int num = top();
		//原始是node1-》node2
		ListNode* tmp = stackTop;// 用 tmp 保存要删除的节点地址
		stackTop = stackTop->next;
		//现在栈顶指向node2
		//(为什么不能)tmp = tmp->next;错误的tmp = tmp->next只做了:
		//修改了临时变量tmp,没有修改stackTop没有删除正确的节点
		delete tmp;//释放内存 这里删除的其实是node1的内存地址
		stksize--;
		return num;
	}

};

//数组栈的实现。
class arratstack {
private:
	vector<int>stack;
public:
	int size() {
		return stack.size();
	}

	bool isempty() {
		return stack.size() == 0;
	}

	void push(int num)
	{
		stack.push_back(num);
	}

	int top() {
		return stack.back();// .back()获取最后一个 .front()获取第一个
	}
	
	//出栈
	int pop()
	{
		/*if (!stack.empty()) {*///要非空才能popback
			int num = top();
			stack.pop_back();
		//}
		
		return num;

	}


};

//队列的链表实现队列 = 先进先出(First In, First Out - FIFO)
//栈 = 后进先出(Last In, First Out - LIFO)

class LinkedlistQueue
{
private:
	ListNode* front, * rear;//前后两个节点指针队列有2个指针
	int quesize;
public:
	LinkedlistQueue() {
		front = nullptr;
		rear = nullptr;
		quesize = 0;
	}

	int size() {
		return quesize;
	}

	bool isempty() {
		return quesize == 0;
	}

	//队尾入队
	void push(int num) {
		ListNode* node = new ListNode(num);//新建节点
		if (front == nullptr) {
			//如果为空,头尾都指向新节点
			front = node;
			rear = node;
		}
		else {
			//如果不为空
			rear->next = node;
			rear = node;

		}
		quesize++;

	}

	//int pop() {
	//	int num = front->getval();
	//	ListNode* tmp = front; //front指向队列队首
	//	tmp->next = front; //第二个指针还是指向队首,变成了自环
	//	delete tmp;
	//	quesize--;

	//	return num;
	//}

	//queue
	//出队,队首出队
	int pop() {
		int num = front->getval();//
		ListNode* gen = front;
		front = front->next;
		delete gen;
		quesize--;
		return num;
	}

	//取队首值
	int peek()
	{
		int num = front->getval();
		return num;
	}

	//转vec方便打印
	vector<int> tovect()
	{
		ListNode* node = front;
		vector<int> res(size());
		for (int i = 0; i < size(); i++)
		{
			res[i] = node->getval();
			node = node->next;
		}
		return res;
	}

};

//数组队列
class arrayQueue {
private:
	int* nums;
	int front;// 队头非空有元素的索引
	int quesize;//当前队列数量
	int quecapacity;//初始化数组总数队列总数
public:
	arrayQueue(int capacity) {
		nums = new int[capacity];//初始化数组数量
		quecapacity = capacity;
		front = quesize = 0;
	}

	int capacity() {
		return quecapacity;
	}
	int size()
	{
		return quesize;
	}

	bool isempty() {
		return size() == 0;
	}

	//入队操作
	void push(int num) {
		
		/* int rear = (front + quesize) % quecapacity;
		 nums[rear] = num;*/
		if (quesize == quecapacity) {
			return;
		}
		//循环队列,队尾满了从队首入队,不循环直接不入队了。
		//初始: [A, B, C, D, _]  front=0, quesize=4 quecapacity=5
		//出队A: [_, B, C, D, _] front = 1, quesize = 3 rear =4 quecapacity=5
		//入队E : [_, B, C, D, E] front = 1, quesize = 4 rear =0 quecapacity=5
		//入队F : [F, B, C, D, E] front = 1, quesize = 5  quecapacity=5
		int rear = (front + quesize) % quecapacity;
		nums[rear] = num;
		quesize++;
	}

	//int peek()
	//{
	//	int num = nums.front();
	//}


	//访问队首元素
	int peek() {
		if (isempty()) return -1;
		//int num_for_nums = front + size() - 1;
		int num = nums[front];
			return num;

	}

	//int pop() {
	//	int num = peek();
	//	//初始: [A, B, C, D, _]  front=0, quesize=4 quecapacity=5
	//	//出队A: [_, B, C, D, _] front = 1, quesize = 3 rear =4 quecapacity=5
	//	front = (front + 1) % quecapacity;
	//	quesize--;
	//	return num;
	//}

	//出队操作
	int pop() {
		int num = peek();//初始: [A, B, C, D, _]  front=0, quesize=4 quecapacity=5
		//出队A: [_, B, C, D, _] front = 1, quesize = 3 rear =4 quecapacity=5
		front = (front + 1) % quecapacity;
		quesize--;
		return num;

	}
};


//双向链表
struct DoublelistNode
{
	int val;
	DoublelistNode* next;//下一个指针
	DoublelistNode* prev;//前序指针
	DoublelistNode(int val) :val(val), prev(nullptr), next(nullptr) {
	}
};

//双向链表
class LinkedlistQueue {
private:
	DoublelistNode* front, * rear;
	int quesize = 0;
public:

	LinkedlistQueue(): front(nullptr), rear(nullptr) {

	}

	~LinkedlistQueue() {
		DoublelistNode* cur = front;
		while (cur != nullptr) {
			DoublelistNode* toDelete = cur;  //现在还是front todelete 记录front地址
			cur = cur->next;//
			delete toDelete;
		}
		// 可选:将指针置空(虽然对象即将销毁)
		front = nullptr;
		rear = nullptr;
	}



	/*~LinkedlistQueue() {
		DoublelistNode* pre, * cur = front;
		while (cur != nullptr) {
			pre = cur;
			cur = cur->next;
			delete pre;
		}

	}*/

	int size() {
		return quesize;
	}


	bool isEmpty() {
		return size() == 0;
	}

	//双向链表入队
	void push(int num, bool isfront) {
		DoublelistNode* node = new DoublelistNode(num);
		if (isEmpty())
			front = rear = node;
		else if (isfront) //如果是前端添加
		{
			// 将 node 添加至链表头部front->A<->B<->C
			//  node->front->a->b
			front->prev = node;
			node->next = front;
			front = node;
		}
		else {
			// 将 node 添加至链表尾部front->A<->B<->C
			//  front->a<->b<->C<-rear <-node
			rear->next = node;
			node->prev = rear;
			rear = node;
		}
		quesize++;
	}

	void pushFirst(int num)
	{
		push(num, 1);
	}

	void pushLast(int num)
	{
		push(num, 0);
	}


	//双向链表出队操作
	int pop(bool isFront) {
		if (isEmpty()) 
			throw out_of_range("队列为空");
		int val;//取值返回
		if (isFront) {//队首出真
			val = front->val;
			DoublelistNode* tmp = front;
			front = front->next;

			// 4. 如果新队头不为空,设置其prev为nullptr
			if (front != nullptr) {
				front->prev = nullptr;
			}
			else {
				// 如果队列变空,rear也要置空
				rear = nullptr;
			}

			delete tmp;

			//原版代码
			//DoublelistNode *fnext = front->next;
			//if (fnext != nullptr) {
			//	fnext->prev = nullptr;
			//	front->next = nullptr;
			//}
			//delete front;
			//front = fnext; // 更新头节点
		}
		//队尾出
		else {
			int val = rear->val;
			DoublelistNode* tmp = rear;
			rear = rear->prev;
			// 2. 处理边界条件
			if (rear != nullptr) {
				// 新队尾不为空,断开与旧队尾的连接
				rear->next = nullptr;
			}
			else {
				// 队列变空,front也要置空
				front = nullptr;
			}
			delete tmp;

		/*	DoublelistNode* fend = rear->prev;
			fend->next = nullptr;
			rear->prev = nullptr;
			delete rear;
			rear = fend;*/
		}
		quesize--;
		return val;
		
	}
	//队首出列
	int popfirst( ) {
		return pop(1);

	}
	//队尾出列
	int poplast() {
		return pop(0);
	}
	//访问队首元素
	int peekfirst() {
		return front->val;
	}
	int peeklast() {
		return rear->val;
	}


};


//双向链表数组实现
class Arraydeque {
private:
	vector<int> nums;
	int front;
	int quesize;
public:
	Arraydeque(int capacity) {
		nums.resize(capacity);
		front = quesize = 0;
	}
	int capacity() {
		return nums.size();
	}
	int size() {
		return quesize;
	}

	bool isempty() {
		return quesize == 0;

	}
	//返回循环数组中的实际索引 队列中第i个元素(从0开始,0是队首)在循环的数组索引:
	//实际上唯一作用就是获取front或者rear当前能入队的数组索引
	int index(int i) {
		//
		return (i + capacity()) % capacity();
	}

	//队首入队
	void pushfirst(int num) {
		if (quesize == capacity()) {
			cout << "满了" << endl;
			return;
		}
		//[_ ,0,4,9]   front =1 cap=4 quesize =3
		//
		front = index(front - 1);
		nums[front] = num;
		quesize++;
	}
	//队尾入队
	void pushlast(int num) {
		if (quesize == capacity()) {
			cout << "满了" << endl;
			return;
		}
		int rear = index(front + quesize);
		nums[rear] = num;
		quesize++;

	}
	int peekfirst() {
		int num = nums[front];
		return num;

	}
	int peeklast() {
		int last = (front + quesize - 1)% quesize;
		return nums[last];
	}
	//队首出队
	int popfirst() {
		int num = peekfirst();
		front = index(front + 1);//更新front
		quesize--;
		return num;
	}
	//队尾出队
	int poplast() {
		int num = peeklast();
		quesize--;
		return num;
	}

};




//数组哈希实现
class Arrayhash {
private:
	vector<pairs*>buckets;
public:
	Arrayhash() {
		buckets = vector<pairs*>(100);
	}
	~Arrayhash() {
		for (const auto& bucket : buckets) {
			delete bucket;
		}
		buckets.clear();
	}

	int hashfunc(int key) {
		int index = key % 100;//哈希函数分配索引
		return index;
	}

	string get(int key) {
		int index = hashfunc(key);
		pairs* pair = buckets[index];
		if (pair == nullptr)
			return"";
		return pair->val;
	}
	//哈希传入
	void put(int key, string val) {
		pairs* pair = new pairs(key, val);
		int index = hashfunc(key);
		buckets[index] = pair;

	}
	//移走
	void remove(int key) {
		int index = hashfunc(key);
		delete buckets[index];
		//buckets.erase(buckets.begin()+index);也可以
	}

	//合并pair,pair包含key+value
	vector<pairs*>pairset() {
		vector<pairs*>pairset;
		for (pairs* pair : buckets) {
			if (pair != nullptr) {
				pairset.push_back(pair);
			}
		}
		return pairset;
	}

	//合并key
	vector<int>keyset(){
		vector<int> keyset;
		for (pairs * pair:buckets) {
			if (pair != nullptr) {
				keyset.push_back(pair->key);
			}
	}
		return keyset;
	}

	//value合并
	vector<string>valueset() {
		vector<string>valueset;
		for (pairs* pair : buckets) {
			if (pair != nullptr) {
				valueset.push_back(pair->val);
			}
		}
		return valueset;
	}

};
//哈希函数
struct pairs {
	int key;
	string val;
	//构造函数
	pairs(int key, string val) :key(key), val(val) {}
};

//链式地址哈希 使用扩容解决哈希冲突unordedmap就是链式
class hashmapchaing {
private:
	int size;                       // 键值对数量
	int capacity;                   // 哈希表容量
	double loadthres;               // 触发扩容的负载因子阈值
	int extendratio;                // 扩容倍数
	vector<vector<pairs*>> buckets; // 桶数组

public:
	hashmapchaing() :size(0), capacity(4), loadthres(2.0 / 3.0), extendratio(2) {
		buckets.resize(capacity);
	}

	~hashmapchaing() {
		for (auto& bucket : buckets) {
			for (pairs* pair : bucket) {
				// 释放内存
				delete pair;
			}
		}
	}

	int hashfunc(int key) {
		return key % capacity;
	}
	/* 负载因子 */
	double loadfactor() {
		return(double)size / (double)capacity;
	}

	//获得key 对应的value查询
	string get(int key) {
		int index = hashfunc(key);
		// 遍历桶,寻找key匹配的pair
		for (pairs* pair : buckets[index]) {
			if (pair->key == key) {      // ✅ 关键:检查key是否匹配
				return pair->val;
			}
		}
		return "";  // 或者返回其他表示未找到的值
	}
	/*buckets数组:
		索引 : 桶内容
		[0] ->[Pair * ptr1, Pair * ptr2, Pair * ptr3]  ← 这是一个vector<Pair*>
		[1] ->[Pair * ptr4]                          ← buckets[1]
		[2] ->[]                                    ← 空桶
		[3] ->[Pair * ptr5, Pair * ptr6]              ← buckets[3]
		当 index = 3 时:
		for (Pair* pair : buckets[3]) {
			// 第一次循环:pair = ptr5
			// 检查ptr5->key == key?
			// 第二次循环:pair = ptr6  
			// 检查ptr6->key == key?
		}*/


	//哈希扩容
	void extend() {
		vector<vector<pairs*>>buckettmp = buckets;
		capacity *= extendratio;//按照扩容倍率扩充
		buckets.clear();
		buckets.resize(capacity);//重新按照扩容后的尺寸resize
		size = 0;
		for (auto& bucket : buckettmp) {
			for (pairs* pair : bucket) {
				put(pair->key, pair ->val);
				delete pair;
			}
		}

	}

	/* 添加操作 */
	void put(int key, string val) {
		// 当负载因子超过阈值时,执行扩容
		if (loadfactor() > loadthres) {
			extend();
		}
		int index = hashfunc(key);
		// 遍历桶,若遇到指定 key ,则更新对应 val 并返回
		for (pairs* pair : buckets[index]) {
			if (pair->key == key) {
				pair->val = val;
				return;
			}
		}
		// 若无该 key ,则将键值对添加至尾部
		buckets[index].push_back(new pairs(key, val));
		size++;
	}
	
	void remove(int key) {
		int index = hashfunc(key);
		auto& bucket = buckets[index];
		for (int i = 0; i < bucket.size(); i++) {
			if (bucket[i]->key == key) {
				pairs* pair = bucket[i];
				bucket.erase(bucket.begin() + i);
				delete pair;
				size--;
				return;
			}
		}

	}

};

//开放寻址哈希
class hashmapopenaddressing {
private:
	int size;
	int capacity = 4;
	const double loadthres = 2.0/3.0;
	const int extendratio = 2;
	vector<pairs*>buckets;
	pairs* TOMBSTONE = new pairs(-1, "-1");

public:
	//构造方法
	hashmapopenaddressing() :size(0), buckets(capacity, nullptr){}
	~hashmapopenaddressing() {
		for (pairs* pair : buckets) {
			if (pair != nullptr && pair != TOMBSTONE) {
				delete pair;

			}
		}
		delete TOMBSTONE;
	}

	int hashfuc(int key) {
		return key % capacity;
	}

	double loadfactor() {
		return (double)size/capacity;
	}
	//搜索key对应的桶索引
	int findBucket(int key) {
		int index = hashfuc(key);
		int firstombstone = -1;
		while (buckets[index] != nullptr) {
			if (buckets[index]->key == key) {
				if (firstombstone != -1) {
					buckets[firstombstone] = buckets[index];
					buckets[index] = TOMBSTONE;
					return firstombstone;
				}
				return index;
			}

		}
			
	}

};

//二叉树
struct TreeNode
{
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}

};
//1
/// \
//2   3
/// \   \
//4   5   6
//队列变化:
//初始 : [1]
//访问1 : 队列→[2, 3]
//访问2 : 队列→[3, 4, 5]
//访问3 : 队列→[4, 5, 6]
//访问4 : 队列→[5, 6]
//访问5 : 队列→[6]
//访问6 : 队列→[]
//结果 : [1, 2, 3, 4, 5, 6]
//binary_tree_bfs层序遍历
vector<int> levelorder(TreeNode* root) {
	//初始化队列,加入根节点
	deque<TreeNode*>queue;
	queue.push_back(root);
	// 初始化一个列表
	vector<int >vec;
	while (!queue.empty()) {
		TreeNode* node = queue.front();
		queue.pop_front();
		vec.push_back(node->val);
		if (node->left != nullptr)
			queue.push_back(node->left);
		if (node->right != nullptr)
			queue.push_back(node->right);
	}

	return vec;
}


//dfs
///1
/// \
//2   3
/// \   \
//4   5   6
//


//第一次压入【1】
//传入1的左节点,把2当作root,压入2【1,2】,
//把2的左4当作root传入压入4【1,2,4】
//把2的右5当作root压入【1,2,4,5】,
//1的右3当作root压入【1,2,4,5,3】
//把3的右当如root压入【1,2,4,5,3,6】

vector<int >vec;
void preorder(TreeNode* root) {
	if (root == nullptr)
		return;
	vec.push_back(root->val); 
	preorder(root->left);	    
	preorder(root->right);                        
}

void inorder(TreeNode* root) {
	if (root == nullptr)
		return;
	inorder(root->left);
	vec.push_back(root->val);
	inorder(root->right);
}
void postorder(TreeNode* root) {
	if (root == nullptr)
		return;
	postorder(root->left);
	postorder(root->right);
	vec.push_back(root->val);
	
}

//
class arraybinarytree {
	public:
		arraybinarytree(vector<int > arr) {
		tree = arr;
	}
		int size() {
			return tree.size();
		}
		int val(int i) {
				if (i < 0 || i >= size())
					return INT_MAX;
				return tree[i];
			}


		/*索引示例:
			节点0:左子 = 1,右子 = 2  (2 * 0 + 1 = 1, 2 * 0 + 2 = 2)
			节点1:左子 = 3,右子 = 4  (2 * 1 + 1 = 3, 2 * 1 + 2 = 4)
			节点2:左子 = 5,右子 = 6  (2 * 2 + 1 = 5, 2 * 2 + 2 = 6)
			节点3:左子 = 7,右子 = 8  (2 * 3 + 1 = 7, 2 * 3 + 2 = 8)*/

	/*		0 (根节点)
			/ \
			1  2
			/ \ / \
			3 4 5  6
			/ \
			7  8 */

		int left(int i) {
			return 2 * i + 1;
		}
		int right(int i) {
			return 2 * i + 2;
		}
		int parent(int i) {
			return (i - 1) / 2;
		}

		//层序遍历
		vector<int> levelorder() {
			vector<int>res;
			for (int i = 0; i < size(); i++) {
				if (val(i) != INT_MAX)
					res.push_back(val(i));
			}
			return res;
		}

		//前序遍历
		vector<int>preorder() {
			vector<int >res;
			dfs(0, "pre", res);
			return res;
		}
		vector<int> inorder() {
			vector<int>res;
			dfs(0, "in", res);
			return res;
		}

		vector<int> postorder() {
			vector<int>res;
			dfs(0, "post", res);
			return res;
		}
private:
	vector<int >tree;

	   /*A(索引0)
		/ \
	  B(1)C(2)
		/ \ /
	 D(3)E(4) F(5)*/

	//dfs(0, "pre", res)				// A
	//	├── res.push_back(A)        // 记录A
	//	├── dfs(1, "pre", res)      // B
	//	│   ├── res.push_back(B)    // 记录B
	//	│   ├── dfs(3, "pre", res)  // D
	//	│   │   ├── res.push_back(D)// 记录D
	//	│   │   └── dfs(7, ...)     // 空,返回
	//	│   │   └── dfs(8, ...)     // 空,返回
	//	│   └── dfs(4, "pre", res)  // E
	//	│       ├── res.push_back(E)// 记录E
	//	│       └── ... 空节点返回
	//	└── dfs(2, "pre", res)      // C
	//	├── res.push_back(C)    // 记录C
	//	├── dfs(5, "pre", res)  // F
	//	│   ├── res.push_back(F)// 记录F
	//	│   └── ... 空节点返回
	//	└── dfs(6, ...)         // 空,返回
	//	结果:[A, B, D, E, C, F]
	void dfs(int i, string order,vector<int > &res ) {
		if (val(i) == INT_MAX)
			return;
		if (order == "pre")
			res.push_back(val(i));
		dfs(left(i), order, res);
		if (order == "in")
			res.push_back(val(i));
		dfs(right(i), order, res);
		if (order == "post") 
			res.push_back(val(i));
	}

	TreeNode* search(int num) {
		TreeNode* root=new TreeNode(num) ;
		TreeNode* cur = root;
		while (cur != nullptr) {
			if (cur->val < num) {
				cur = cur->right;
			}
			else if (cur->val > num)
			{
				cur = cur->left;
			}
			else
				break;

		}
		return cur;
	}
};

void insert(int num, TreeNode* root) {
	/*TreeNode* root = new TreeNode(num);*/
	if (root == nullptr) {
		root = new TreeNode(num);
	}

	TreeNode* cur = root, * pre = nullptr;
	while (cur != nullptr)
	{
		if (cur->val == num)
		{
			return;
		}
		pre = cur;//第12行:记录父节点。作用:在移动 cur 之前,用 pre 记录当前位置。这样当 cur 变为 nullptr 时,pre 就是要插入位置的父节点
		if (cur->val < num)
			cur = cur->right;
		else
			cur = cur->left;
	}

	TreeNode* node = new TreeNode(num);
	if (pre->val < num)
		pre->right = node;
	else
		pre->left = node;

}

void delete_tree_node(int num, TreeNode* root)
{
	if (root == nullptr)
		return;
	TreeNode* cur = root, * pre = nullptr;//父节点
	while (cur != nullptr)
	{
		if (cur->val == num) {
			break;
		}
		pre = cur;
		//待删除节点在cur的右子树
		if (cur->val < num)
			cur = cur->right;
		else
			cur = cur->left;

	}
	if (cur == nullptr)
		return;
	//子节点数量=0or1
	if (cur->left == nullptr || cur->right == nullptr) {
		//cur子节点有一个为空 child =null/该子节点逻辑:
		// 如果左子节点不为空 → child = 左子节点
        //否则 → child = 右子节点(可能为空)
		//结果:0个子节点:child = nullptr 1个子节点:child = 那个非空的子节点
		TreeNode* child = cur->left != nullptr ? cur->left : cur->right;
		if (cur != root) {
			if (pre->left == cur)
				pre->left = child;
			else
				pre->right = child;
		}
		else {
			root = child;
		}
		delete cur;
	}
	else {
		TreeNode* tmp = cur->right;
		//cur一定有2个子节点
		while (tmp->left != nullptr) {
			tmp = tmp->left;
		}
		int tmpval = tmp->val;
		delete_tree_node(tmp->val,root);
		//递归删除找到待删除节点的非空左子节点并删除,然后把这个值赋给最开始找到的子节点。
		cur->val = tmpval;
	}

}





int main() {


TreeNode* n1 = new TreeNode(1);
TreeNode* n2 = new TreeNode(2);
TreeNode* n3 = new TreeNode(3);
TreeNode* n4 = new TreeNode(4);
TreeNode* n5 = new TreeNode(5);
// 构建节点之间的引用(指针)
	n1->left = n2;
	n1->right = n3;
	n2->left = n4;
	n2->right = n5;

	TreeNode* p = new TreeNode(0);
	n1->left = p;
	p->left = n2;
	n1->left = p;
	delete p;
	

}



//int main12301()
//{
//	ListNode* n0 = new ListNode(1);
//	ListNode* n1 = new ListNode(2);
//	ListNode* n2 = new ListNode(3);
//	ListNode* n3 = new ListNode(4);
//	ListNode* n4 = new ListNode(2);
//
//	n0->next = n1;
//	n1->next = n2;
//	n2->next = n3;
//	n3->next = n4;
//
//
//
//
//	int i = find( n0, 2);
//	std::cout << i << std::endl;
//		
//
//	deque<int >de;
//	de.push_back(2);
//	de.push_back(5);
//	de.push_front(10);
//
//	int front = de.front();
//	int back = de.back();
//	de.pop_back();
//	de.pop_front();
//	int size = de.size();
//
//	bool empty = de.empty();
//
//	
//
//
//
//}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜是菜人是真帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值