c++学习第十六天

创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。


提示:以下是本篇文章正文内容,下面案例可供参考。

一、优先级队列

  1.大堆

#include<iostream>
#include<queue>
using namespace std;

int main()
{
	priority_queue<int> q;
    //priority_queue<int, vector<int>, less<int>> q;
	q.push(8);
	q.push(6);
	q.push(4);
	q.push(9);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl;

	return 0;
}


  2.小堆

#include<iostream>
#include<queue>
using namespace std;

int main()
{
	priority_queue<int,vector<int>,greater<int>> q;
	q.push(8);
	q.push(6);
	q.push(4);
	q.push(9);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl;

	return 0;
}


二、二叉搜索树

 


  1.下面操作采用循环的方式

       ①创建和中序遍历

//Test.cpp
#include"BinarySearchTree.h"

int main()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> bt;
	for (auto e : a)
		bt.Insert(e);
	bt._InOrder();
	return 0;
}
//BinarySearchTree.h
#pragma once
#include<iostream>
using namespace std;

template<class K>
struct BSTreeNode
{
	BSTreeNode<K>* left;
	BSTreeNode<K>* right;
	K _key;
	BSTreeNode(const K& key)
		:left(nullptr)
		,right(nullptr)
		,_key(key)
	{}
};

template<class K>
class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	bool Insert(const K& key)
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			parent = cur;
			if (cur->_key < key)
				cur = cur->right;
			else if (cur->_key > key)
				cur = cur->left;
			else
				return false;
		}
		cur = new Node(key);
		if (parent->_key > key)
			parent->left = cur;
		else
			parent->right = cur;
		return false;
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->left);
		cout << root->_key << " ";
		_InOrder(root->right);
	}
	void _InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
private:
	Node* _root = nullptr;
};


      ②查找

//Test.cpp
#include"BinarySearchTree.h"

int main()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> bt;
	for (auto e : a)
		bt.Insert(e);
	bt._InOrder();

	cout << bt.Find(1) << endl;

	return 0;
}
//BinarySearchTree.h

bool Find(const K& key)
{
	Node* cur = _root;
	while (cur)
	{
		if (cur->_key > key)
			cur = cur->left;
		else if (cur->_key < key)
			cur = cur->right;
		else
			return true;
	}
	return false;
}


      ③删除

//Test.cpp
#include"BinarySearchTree.h"

int main()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> bt;
	for (auto e : a)
		bt.Insert(e);
	bt._InOrder();

	bt.Erase(14);
	bt._InOrder();

	bt.Erase(3);
	bt._InOrder();

	bt.Erase(8);
	bt._InOrder();

	return 0;
}
//BinarySearchTree.h

bool Erase(const K& key)
{
	Node* parent = nullptr;
	Node* cur = _root;
	while (cur)
	{
		if (cur->_key > key)
		{
			parent = cur;
			cur = cur->left;
		}
		else if (cur->_key < key)
		{
			parent = cur;
			cur = cur->right;
		}
		else 
		{
			// 准备删除
			if (cur->left == nullptr)
			{//左为空,有两种情况
				if (cur == _root)
					_root = cur->right;
				else
				{
					//节点在整个树的左子树
					if (cur == parent->left)
						parent->left = cur->right;
					//节点在整个树的右子树
					else
						parent->right = cur->right;
				}
				delete cur;
			}
			else if (cur->right == nullptr)
			{//右为空
				if (cur == _root)
					_root = cur->left;
				else
				{
					//节点在整个树的左子树
					if (cur == parent->left)
						parent->left = cur->left;
					//节点在整个树的右子树
					else
						parent->right = cur->left;
				}
				delete cur;
			}
			else
			{//左右都不为空

				// 右树的最小节点(最左节点)
				Node* parent = cur;
				//Node* parent = nullptr;不要这样写,会出现空指针的问题
				Node* subleft = cur->right;
				while (subleft->left)
				{
					parent = subleft;
					subleft = subleft->left;
				}
				swap(cur->_key, subleft->_key);
				if (subleft == parent->left)
					parent->left = subleft->right;
				else
					parent->right = subleft->right;
				delete subleft;
			}
			return true;
		}
	}
	return false;
}


  2.下面操作采用递归的方式(推荐)

     以_InOrder()为例解释public下的_InOrder()和private下的_InOrder(Node* root):主函数处调用下面的_InOrder(),然后_InOrder()调用private的_InOrder(Node* root) .

     ①创建和中序遍历

//BinarySearchTree.h
#pragma once
#include<iostream>
using namespace std;

template<class K>
struct BSTreeNode
{
	BSTreeNode<K>* left;
	BSTreeNode<K>* right;
	K _key;
	BSTreeNode(const K& key)
		:left(nullptr)
		,right(nullptr)
		,_key(key)
	{}
};
template<class K>
class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	void _InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	bool InsertR(const K& key)
	{
		return _InsertR(_root, key);
	}
private:
	Node* _root = nullptr;
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->left);
		cout << root->_key << " ";
		_InOrder(root->right);
	}
	bool _InsertR(Node*& root, const K& key)
	{//不能写成bool _InsertR(Node*& root, const K & key),加上&取别名来链接插入的节点
	 //别名作用:实则指向的是要插入节点的父节点
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}
		if (root->_key > key)
			return _InsertR(root->left, key);
		else if (root->_key < key)
			return _InsertR(root->right, key);
		else
			return false;
	}
};
//Test.cpp

#include"BinarySearchTree.h"

int main()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> bt;
	for (auto e : a)
		bt.InsertR(e);
	bt._InOrder();

	return 0;
}

     ②查找

class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}
private:
	Node* _root = nullptr;
	bool _FindR(Node* root, const K& key)
	{
		if (root == nullptr)
			return false;
		if (root->_key > key)
			return _FindR(root->left, key);
		else if (root->_key < key)
			return _FindR(root->right, key);
		else
			return true;
	}
};

     ③删除

class BSTree
{
	typedef BSTreeNode<K> Node;
public:
	bool EraseR(const K& key)
	{
		return _EraseR(_root, key);
	}
private:
	Node* _root = nullptr;

	bool _EraseR(Node*& root, const K& key)
	{
		if (root == nullptr)
			return false;
		if (root->_key > key)
			return _EraseR(root->left, key);
		else if (root->_key < key)
			return _EraseR(root->right, key);
		else
		{
			// 删除
			if (root->left == nullptr)
			{//左子树为空,此时root实则是父节点的右指向的别名
				Node* del = root;
				root = root->right;
				delete del;
				return true;
			}
			else if (root->right == nullptr)
			{//右子树为空,此时root实则是父节点的左指向的别名
				Node* del = root;
				root = root->left;
				delete del;
				return true;
			}
			else 
			{
				Node* subLeft = root->right;
				while (subLeft->left)
				{
					subLeft = subLeft->left;
				}
				swap(root->_key, subLeft->_key);
				// 转换成在子树去递归删除
				return _EraseR(root->right, key);
			}
		}
	}
};

    ④构造和析构函数

BSTree()
	{
	}
	BSTree(const BSTree<K>& t)
	{
		_root = Copy(t._root);
	}
	~BSTree()
	{
		Destroy(_root);
	}
private:
	Node* _root = nullptr;
	Node* Copy(Node* root)
	{
		if (root == nullptr)
			return nullptr;
		Node* newNoot = new Node(root->_key);
		newNoot->left = Copy(root->left);
		newNoot->right = Copy(root->right);
		return newNoot;
	}
	void Destroy(Node*& root)
	{
		if (root == nullptr)
			return;
		Destroy(root->left);
		Destroy(root->right);
		delete root;
		root = nullptr;
	}
//Test.cpp

#include"BinarySearchTree.h"

int main()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	BSTree<int> bt;
	for (auto e : a)
		bt.InsertR(e);
	bt._InOrder();

	BSTree<int> copy(bt);
	copy._InOrder();

	return 0;
}


    ⑤赋值

BSTree<K>& operator=(BSTree<K> t)
{
	swap(_root, t._root);
	return *this;
}

三、习题

  1.数组中的第K个最大元素

//力扣代码
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> pq(nums.begin(),nums.end());
        while(--k)
        {
            pq.pop();
        }
        return pq.top();
    }
};


总结

      例如:以上就是今天要讲的内容,本文仅仅简单介绍了c++的基础知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jacob~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值