0
点赞
收藏
分享

微信扫一扫

电学基础概念详解及三相电公式汇总

40dba2f2a596 2024-09-18 阅读 22

3.递归

在函数定义中,出现自己调用自己的情形,称为递归。

递归的特点:

自身调用:原问题可以分解为子问题,子问题的求解方法和原问题是一致的,即都是调用自身同一个函数。

终止条件:递归必须有一个终止条件,即不能无限的调用自身。

经典的递归例子,汉诺塔问题:

设于三根标号为A,B,C的柱子,在A柱上放着n个盘子,每个盘子都比下面的盘子小一些,要求把A柱上的盘子全部移动到C柱上。移动的规则为:

1.一次只能移动一个盘子;

2.移动过程中,大盘子不能放在小盘子上面;

3.在移动过程中,盘子可以放在A,B,C的任意一个柱子上。

递归存在的问题:

当递归调用的层级太多时,就可能超出栈的容量,从而导致栈溢出。

重复计算,导致程序效率低下。

#include <iostream>
using namespace std;


//求n的阶乘
int factorial(int n)
{
	if (n == 1)
	{
		return 1;
	}
	return n * factorial(n - 1);
}

int sum = 0;
//求解汉诺塔问题
void move(char m, char n)
{
	cout << m << "---->" << n << endl;
	sum++;
}
void hanoi(int n, char a, char b, char c)
{
	//借助b柱,将n个盘子从a柱移动到c柱
	if (n == 1)
	{
		move(a, c);
	}
	else
	{
		hanoi(n - 1, a, c, b);//借助c柱,将前n-1个盘子从a柱移动到b柱
		move(a, c);//将剩下的n号盘子从a柱移动到c柱
		hanoi(n - 1, b, a, c);//借助a柱,将前n-1个盘子从b柱移动到c柱

	}
	
}
int main()
{
	//cout << "5的阶乘是:" << factorial(5) << endl;
	int n;
	cout << "请输入盘子个数:";
	cin >> n;
	cout << "移动" << n << "个盘子的过程:" << endl;
	hanoi(n, 'A', 'B', 'C');
	cout << "总共运行:" << sum << endl;
	return 0;
}

4.受限线性表

4.1栈(stack)

栈是一种特殊的线性表,只能在栈顶进行插入和删除操作,一般不能遍历数据。先进后出(FILO) 

栈的应用:

所有的编译器(解释器)都有检测括号是否匹配的功能,如何检测呢?

例如,有如下字符串“6x(5+(3x(5-2)))”

要求,写一个函数,利用链式栈来判断字符串中小括号是否匹配

算法思路:

遍历字符串,碰到普通字符,忽略,当碰到左括号时入栈,碰到右括号时出栈,遍历完整个字符串后,如果栈为空,则说明匹配,否则不匹配。

设计一个栈的数据结构,用来计算一个逆波兰式。

算法思路:

遍历字符串碰到数字入栈,碰到符号,先从栈中弹出右操作数,再从栈中弹出左操作数,然后根据符号进行运算,再把运算结果入栈。。。。直到字符串遍历完毕。最后栈中唯一的数字即为结果。

顺序栈:

#pragma once

#define MAX_SIZE 512

class SeqStack
{
private:
	int* data;
	int size;

public:
	SeqStack();
	~SeqStack();


	//入栈
	void push(int value);
	void pop(); //出栈
	int getSize();//返回栈大小
	int top();//返回栈顶元素
	bool isEmpty();//判断栈是否为空
	void clear();// 清空栈

};


//.c

#include <iostream>
#include "seqStack.h"
using namespace std;


SeqStack::SeqStack()
{
	data = new int[MAX_SIZE];
	size = 0;
}

SeqStack::~SeqStack()
{
	if (data != nullptr)
	{
		delete[]data;
		data = nullptr;
	}
}

void SeqStack::push(int value)
{
	if (size == MAX_SIZE)
	{
		return;
	}
	data[size] = value;
	size++;
}
void SeqStack::pop()
{
	if (size > 0)
	{
		size--;
	}
}

int  SeqStack::getSize()
{
	return size;
}

int SeqStack::top()
{
	if (size > 0)
	{
		return data[size - 1];
	}
	return NULL;
}

bool SeqStack::isEmpty()
{
	if (size == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
	// return size == 0;
}

void SeqStack::clear()
{
	size = 0;
}


void test_seqstack()
{
	SeqStack seqstack;
	cout << "栈的大小为:" << seqstack.getSize() << endl;
	cout << "栈是否为空:" << seqstack.isEmpty() << endl;
	for (int i = 0; i < 8; i++)
	{
		seqstack.push(i + 50);

	}
	cout << "栈的大小为:" << seqstack.getSize() << endl;
	cout << "栈是否为空:" << seqstack.isEmpty() << endl;

	cout << "栈顶的元素为:" << seqstack.top() << endl;
}

链式栈:

解决栈内字符串内的括号是否匹配;计算逆波兰式

#pragma once

class LinkStackNode
{
public:
	int data;
	LinkStackNode* next;

public:
	LinkStackNode();
	LinkStackNode(int value);


};

class LinkStack
{
private:
	LinkStackNode* head;
	int size;

public:
	LinkStack();
	~LinkStack();

	
	void push(int value);//入栈
	void pop();//出栈
	int getSize();//返回栈的大小
	int top();//返回栈顶元素
	bool isEmpty();//判断栈是否为空
	void clear();//清空栈
};

//.c

#include <iostream>
#include "linkStack.h"
using namespace std;

LinkStackNode::LinkStackNode()
{
	data = NULL;
	next = nullptr;
}

LinkStackNode::LinkStackNode(int value)
{
	data = value;
	next = nullptr;
}

LinkStack::LinkStack()
{
	head = new LinkStackNode();
	size = 0;
}

LinkStack::~LinkStack()
{
	LinkStackNode* curr = head;
	LinkStackNode* temp = nullptr;
	while (curr != nullptr)
	{
		temp = curr;
		curr = curr->next;
		delete temp;
	}
}

void LinkStack::push(int value)
{
	//新建节点
	LinkStackNode* newNode = new LinkStackNode(value);
	//新节点插在最前面
	newNode->next = head->next;
	head->next = newNode;

	size++;
}

void LinkStack::pop()
{
	if (size > 0)
	{
		//删除第一个节点
		LinkStackNode* temp = head->next;
		head->next = temp->next;
		delete temp;

		size--;
	}
}

int LinkStack::getSize()
{
	return size;
}

int LinkStack::top()
{
	if (size > 0)
	{
		return head->next->data;
	}
	return NULL;
}

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

void LinkStack::clear()
{
	while (size > 0)
	{
		pop();
	}
}

void text_linkstack()
{
	LinkStack* ls = new LinkStack();
	cout << "栈大小为:" << ls->getSize() << endl;
	cout << "栈是否为空:" << ls->isEmpty() << endl;
	for (int i = 0; i < 8; i++)
	{
		ls->push(i + 50);
	}
	cout << "栈大小为:" << ls->getSize() << endl;
	cout << "栈是否为空:" << ls->isEmpty() << endl;
	cout << "栈顶元素为:" << ls->top() << endl;
	ls->pop();
	ls->pop();
	ls->pop();
	cout << "栈顶元素为:" << ls->top() << endl;
}

//判断括号是否匹配
bool match(string s)
{
	LinkStack* ls = new LinkStack();
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == '(')
		{
			ls->push(s[i]);
		}
		else if (s[i] == ')')
		{
			if (ls->isEmpty())
			{
				return false;
			}
			else
			{
				ls->pop();
			}
		}
	}
	return ls->isEmpty();
	
}
void test_match()
{
	string str1 = "6s(8i()8c())";
	if (match(str1))
	{
		cout << "小括号匹配" << endl;
	}
	else
	{
		cout << "小括号不匹配" << endl;
	}

}

//逆波兰式
int suffix_compute(string s)
{
	LinkStack ls;
	for (int i = 0; i < s.size(); i++)
	{
		if (s[i] >= '0' && s[i] <= '9')
		{
			ls.push((s[i] - '0'));
			cout << ls.top() << endl;
		}
		else
		{
			int n = ls.top();//右值
			ls.pop();
			int m = ls.top();//左值
			ls.pop();
			int m_n = 1;
			if (s[i] == '+')
			{
				m_n = m + n;
			}
			if (s[i] == '-')
			{
				m_n = m - n;
			}
			if (s[i] == '*')
			{
				m_n = m * n;
			}
			if (s[i] == '/')
			{
				m_n = m / n;
			}
			ls.push(m_n);
		}
	}
	return ls.top();
}

void test_suffix_compute()
{
	string str1 = "831-5*+";
	cout << "计算结果为:" << suffix_compute(str1) << endl;
}

4.2队列(queue)

队列是另外一种特殊的线性表,只允许在一端进行插入操作,而在另一端进行删除操作,允许插入的一端称为队尾,,允许删除的一段称为队头。先进先出(FIFO)

顺序队列:

//SeqQueue.h

#pragma once
#define MAX_SIZE 512


class SeqQueue
{
private:
	int* data;
	int size;
public:
	SeqQueue();
	~SeqQueue();


	void push(int value);//从队尾入队
	void pop();// 出队,从队头出
	int  getSize();
	int front();
	int back();
	bool isEmpty();
	void clear();//清空

};

//SeqQueue.c

#include <iostream>
#include"seqQueue.h"
using namespace std;

SeqQueue::SeqQueue()
{
	data = new int[MAX_SIZE];
	size = 0;
}

SeqQueue::~SeqQueue()
{
	if (data != nullptr)
	{
		delete[]data;
		data = nullptr;
	}
}

void SeqQueue::push(int value)
{
	if (size == MAX_SIZE)
	{
		return;
	}
	data[size++] = value;
}

void SeqQueue::pop()
{
	if (size > 0)
	{
		for (int i = 0; i < size - 1 ; i++)
		{
			data[i] = data[i + 1];
		}
		size--;
	}
	
}

int SeqQueue::getSize()
{
	return size;
}

int SeqQueue::front()
{
	if (size > 0)
	{
		return data[0];
	}
	return NULL;
}

int SeqQueue::back()
{
	if (size > 0)
	{
		return data[size - 1];
	}return NULL;
}

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

void SeqQueue::clear()
{
	size = 0;
}


void test_seqqueue()
{
	SeqQueue* seq = new SeqQueue;
	cout << "队列的大小为:" << seq->getSize() << endl;
	cout << "队列是否为空:" << seq->isEmpty() << endl;

	for (int i = 0; i < 8; i++)
	{
		seq->push(i + 70);
	}
	cout << "队列的大小为:" << seq->getSize() << endl;
	cout << "队列是否为空:" << seq->isEmpty() << endl;
	cout << "队头元素:" << seq->front() << endl;
	cout << "队尾元素:" << seq->back() << endl;

	seq->pop();
	seq->pop();
	cout << "队头元素:" << seq->front() << endl;
	cout << "队列的大小为:" << seq->getSize() << endl;

	seq->clear();
	cout << "队列的大小为:" << seq->getSize() << endl;
}

链式队列:

练习:设计一个队列,用来解决约瑟夫问题。

//LinkQueue.h

#pragma 

class LinkQueueNode
{
public:
	int data;
	LinkQueueNode* next;

public:
	LinkQueueNode();
	LinkQueueNode(int value);
};

class linkQueue
{
private:
	int size;
	LinkQueueNode* head;

public:
	linkQueue();
	~linkQueue();


	void push(int value);
	void pop();
	int getSize();
	int back();
	int front();
	int top();
	bool isEmpty();
	void clear();

};

//LinkQueue.c

#include <iostream>
#include "linkQueue.h"
using namespace std;


LinkQueueNode::LinkQueueNode()
{
	data = NULL;
	next = nullptr;
}

LinkQueueNode::LinkQueueNode(int value)
{
	data = value;
	next = nullptr;
}

linkQueue::linkQueue()
{
	size = 0;
	head =new LinkQueueNode();
}

linkQueue::~linkQueue()
{
	LinkQueueNode* curr = head;
	LinkQueueNode* temp = nullptr;
	while (curr != nullptr)
	{
		temp = curr;
		curr = curr->next;
		delete temp;	
	}
}


void linkQueue::push(int value)
{
	LinkQueueNode* newNode = new LinkQueueNode(value);
	LinkQueueNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
	}
	
	curr->next = newNode;

	size++;
}

int linkQueue::getSize()
{
	return size;
}
void linkQueue::pop()
{

	if (size == 0)
	{
		return;
	}
	LinkQueueNode* temp = head->next;
	head->next = temp->next;
	delete temp;

	size--;
}


int linkQueue::back()
{
	if (size == 0)
	{
		return NULL;
	}
	LinkQueueNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
	}
	return curr->next->data;
}

int linkQueue::front()
{
	return head->next->data;
}
bool linkQueue::isEmpty()
{
	return size == 0;
}

void test_linkqueue()
{
	linkQueue lk;
	for (int i = 0; i < 8; i++)
	{
		lk.push(i + 20);
		
	}
	cout << lk.getSize() << endl;
}

//约瑟夫问题
void test_yuesefu()
{
	linkQueue* lk = new linkQueue;
	for (int i = 0; i < 8; i++)
	{
		lk->push(i);

	}
	int n = 8;
	int m = 3;
	while (!lk->isEmpty())
	{
		for (int i = 1; i < 5; i++)
		{
			int temp = lk->front();
			lk->pop();
			lk->push(temp);
		}
		cout << lk->front() << " ";
		lk->pop();
	}
	delete[]lk;
	
}

5.树

5.1树的基本概念

定义:由零个或者多个(n>=0)节点组成的有限集合,有且仅有一个节点称为根(root),当n>1时,其余节点可以分为m个互不相交的有限集合。每个集合本身又是一棵树,称为这个根的子树。

特点:非线性结构,,每个节点(除了根之外)都有一个直接前驱,但是有可能有多个直接后继;

树的定义具有递归性,树中还有树;

树可以为空,即节点个数为0。

树的术语: 根(root):即根节点,没有前驱;

叶子(leaf):即终端节点,没有后继;

双亲(parent):即节点的直接前驱;

孩子(child):即节点的直接后继;

兄弟(sibling):同一个双亲下的节点;

堂兄弟(cousin):双亲为兄弟的节点;

节点的度:节点下挂接的子树个数

树的度:树中节点度的最大值

节点的层数:从根开始到该节点的层数(根为第一层)

树的深度(高度):树中所有节点的最大层数

5.2二叉树

定义:n(n>=0)个节点的有限集合,由一个根节点以及最多两个互不相交的子树组成,也就是度为2的树。

二叉树的性质:

在二叉树的第i层上最多有2^i-1^个节点;

深度为k的二叉树上最多有2^k^-1个节点。

满二叉树:每一层都充满了节点,除了叶子之外的所有节点的度都是2。

深度为k的满二叉树上的节点个数为2^k^-1。

完全二叉树:除了最后一层,每一层上的节点数均达到最大值,在最后一层上只缺少右边的若干节点。

特点:高度为k的完全二叉树,k-1层是满二叉树,第k层上的节点都靠左

性质:对于一颗完全二叉树,如果从上到下,从左到右,给树中节点编号,根节点编号为0的话,则编号为i的节点,其左孩子编号为2i+1,右孩子编号为2i+2,双亲编号为(i-1)/2

练习:

计算一颗二叉树叶子节点的个数

计算一颗二叉树的高度

//binaryTree.h

#pragma once

class BinaryTreeNode
{
public:
	int data;
	BinaryTreeNode* left;
	BinaryTreeNode* right;

public:
	BinaryTreeNode();
	BinaryTreeNode(int value);
};

//binaryTree.c

#include <iostream>
#include"binaryTree.h"
using namespace std;

BinaryTreeNode::BinaryTreeNode()
{
	data = NULL;
	left = nullptr;
	right = nullptr;
}

BinaryTreeNode::BinaryTreeNode(int value)
{
	data = value;
	left = nullptr;
	right = nullptr;
}


BinaryTreeNode* createBinaryTree()
{
	BinaryTreeNode* a = new BinaryTreeNode(1);
	BinaryTreeNode* b = new BinaryTreeNode(2);
	BinaryTreeNode* c = new BinaryTreeNode(3);
	BinaryTreeNode* d = new BinaryTreeNode(4);
	BinaryTreeNode* e = new BinaryTreeNode(5);
	BinaryTreeNode* f = new BinaryTreeNode(6);
	BinaryTreeNode* g = new BinaryTreeNode(7);
	BinaryTreeNode* h = new BinaryTreeNode(8);
	BinaryTreeNode* i = new BinaryTreeNode(9);
	BinaryTreeNode* j = new BinaryTreeNode(10);

	a->left = b;
	a->right = c;
	b->left = d;
	b->right = e;
	c->left = f;
	c->right = g;
	d->left = h;
	d->right = i;
	e->left = j;

	return a; 
}

//先序遍历:根->左子树->右子树
void preOrder(BinaryTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	cout << root->data << " ";
	preOrder(root->left);//递归遍历左子树
	preOrder(root->right);//递归遍历右子树
}

//中序遍历: 左子树->根->右子树
void inOrder(BinaryTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	inOrder(root->left);//递归遍历左子树
	cout << root->data << " ";
	inOrder(root->right);//递归遍历右子树
}
//后序遍历:左子树->右子树->根
void postOrder(BinaryTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	postOrder(root->left);//递归遍历左子树
	postOrder(root->right);//递归遍历右子树
	cout << root->data << " ";
}


//计算二叉树的叶子节点
int calculateLeafNum(BinaryTreeNode* root)
{
	
	if (root == nullptr)
	{
		return 0;
	}
	else if (root->left== nullptr && root->right == nullptr)
	{
		return 1;
	}
	
	return calculateLeafNum(root->left) + calculateLeafNum(root->right);
	
	
}

//计算二叉树的高度
int binaryTree_height(BinaryTreeNode* root)
{
	if (root == nullptr)
	{
		return 0;
	}
	/*if (root->left != nullptr)
	{
		return 1;
	}
	if (root->right != nullptr)
	{
		return 1;
	}*/
	return ((binaryTree_height(root->left) > binaryTree_height(root->right)) ? binaryTree_height(root->left) : binaryTree_height(root->right))+ 1 ;
}

int main()
{
	BinaryTreeNode* root = createBinaryTree();
	cout << "先序遍历:";
	preOrder(root);
	cout << endl;
	cout << "中序遍历:";
	inOrder(root);
	cout << endl;
	cout << "后序遍历:";
	postOrder(root);
	cout << endl;
	cout << "此二叉树的叶子节点的个数为:" << calculateLeafNum(root) << endl;
	
	cout << "此二叉树的高度为: " << binaryTree_height(root) << endl;

	return 0;
}

5.3二叉搜索树

一颗二叉树的左子树上的节点都小于树根,右子树的节点都大于树根,对于任意一个节点及其子树,均要满足此要求。这样的树,称为二叉搜索树,亦称二叉排序树。

对于一颗二叉搜索树进行中序遍历的话,其结果为一个有序序列。

如何构建一颗二叉搜索树?

给一个序列,7 4 5 6 1 8 9,用来构建一颗二叉搜索树。

在一颗二叉搜索树上进行查找操作,最大查找次数,就是树的深度,类似于折半查找,每次都排除一半的树。

//binarySearchTree.h

#pragma once

class BinarySearchTreeNode
{
public:
	int data;
	BinarySearchTreeNode* left;
	BinarySearchTreeNode* right;

public:
	BinarySearchTreeNode();
	BinarySearchTreeNode(int value);
};


//binarySearchTree.c

#include <iostream>
#include"binarySearchTree.h"
using namespace std;

BinarySearchTreeNode::BinarySearchTreeNode()
{
	data = NULL;
	left = nullptr;
	right = nullptr;
}

BinarySearchTreeNode::BinarySearchTreeNode(int value)
{
	data = value;
	left = nullptr;
	right = nullptr;
}

//先序遍历:根->左子树->右子树
void preOrder(BinarySearchTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	cout << root->data << " ";
	preOrder(root->left);//递归遍历左子树
	preOrder(root->right);//递归遍历右子树
}

//中序遍历: 左子树->根->右子树
void inOrder(BinarySearchTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	inOrder(root->left);//递归遍历左子树
	cout << root->data << " ";
	inOrder(root->right);//递归遍历右子树
}
//后序遍历:左子树->右子树->根
void postOrder(BinarySearchTreeNode* root)
{
	if (root == nullptr)
	{
		return;
	}
	postOrder(root->left);//递归遍历左子树
	postOrder(root->right);//递归遍历右子树
	cout << root->data << " ";
}

//构建二叉搜索树,不用返回值
void addNode(BinarySearchTreeNode*& root, int value)
{
	if (root == nullptr)
	{
		root = new BinarySearchTreeNode(value);
		
	}
	if (root->data > value)
	{
		addNode(root->left, value);//添加左子树
	}
	if (root->data < value)
	{
		addNode(root->right, value);//添加右子树
	}
	
}
//构建二叉搜索树,有返回值
BinarySearchTreeNode* addNode2(BinarySearchTreeNode* root, int value)
{
	if (root == nullptr)
	{
		root = new BinarySearchTreeNode(value);
	}
	else if (root->data > value)
	{
		root->left = addNode2(root->left, value);//添加左子树
	}
	else if (root->data < value)
	{
		root->right = addNode2(root->right, value);//添加右子树
	}

	return root;
}
// 构建二叉搜索树,非递归函数
void addNode3(BinarySearchTreeNode* root, int value)
{
	//新建节点
	BinarySearchTreeNode* newNode = new BinarySearchTreeNode(value);
	BinarySearchTreeNode* temp = root;
	while (temp != nullptr)
	{
		if (temp->data > value)//左插
		{
			if (temp->left == nullptr)
			{
				temp->left = newNode;
				return;
			}
			else
			{
				temp = temp->left;
			}
		}
		else if (temp->data < value)//右插
		{
			if (temp->right == nullptr)
			{
				temp->right = newNode;
				return;
			}
			else
			{
				temp = temp->right;
			}			
		}
	}
}
void test_addnode()
{
	int a[] = { 7,4,5,6,1,8,9 };
	int lenght = sizeof(a) / sizeof(a[0]);

	BinarySearchTreeNode* root = nullptr;
	for (int i = 0; i < lenght; i++)
	{
		addNode(root, a[i]);
	}
	inOrder(root);
} 

void test_addnode2()
{
	int a[] = { 7,4,5,6,1,8,9 };
	int lenght = sizeof(a) / sizeof(a[0]);

	BinarySearchTreeNode* root = nullptr;
	for (int i = 0; i < lenght; i++)
	{
		root = addNode2(root, a[i]);
	}
	inOrder(root);
}
void test_addnode3()
{
	int a[] = { 7,4,5,6,1,8,9 };
	int lenght = sizeof(a) / sizeof(a[0]);

	BinarySearchTreeNode* root = new BinarySearchTreeNode(a[0]);
	for (int i = 1; i < lenght; i++)
	{
		addNode3(root, a[i]);
	}
	inOrder(root);
}

// 在二叉树上查找节点
bool searchBinaryTree(BinarySearchTreeNode* root , int value)
{
	cout << "=====查找=====" << endl;
	static int sum = 0;
	sum++;
	cout << "查找次数为:" << sum << endl;
	if (root == nullptr)
	{
		
		return false;

	}
	if (root->data == value)
	{
		
		return true;
		
	}
	if (root->data > value)
	{
		
		return searchBinaryTree(root->left, value);
		
	}
	if (root->data < value)
	{
		
		return searchBinaryTree(root->right, value);
	}
	return sum;
}

void test_search()
{
	int a[] = { 7,4,5,6,1,8,9 };
	int lenght = sizeof(a) / sizeof(a[0]);

	BinarySearchTreeNode* root = nullptr;
	for (int i = 0; i < lenght; i++)
	{
		addNode(root, a[i]);
	}
	if (searchBinaryTree(root, 10))
	{
		cout << " 找到了";
	}
	else
	{
		cout << "找不到";
	}
	cout << endl;
	
}
//计算二叉树的高度
int binaryTree_height(BinarySearchTreeNode* root)
{
	if (root == nullptr)
	{
		return 0;
	}
	return ((binaryTree_height(root->left) > binaryTree_height(root->right)) ? binaryTree_height(root->left) : binaryTree_height(root->right)) + 1;
}

5.4平衡二叉树

二叉搜索树的优点就是查找效率很高,但是在某些极端情况下,例如给一个序列,1 2 3 4 5 6 7,用次序列构建的二叉搜索树将退化成一个线性表,其查找时间复杂度将变为O(n),因此我们需要将这种二叉搜索树调整为平衡二叉树。

平衡二叉树:是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。

平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。  最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。

判断一颗二叉树是否是平衡二叉树
//判断一颗二叉树是否是平衡二叉树
bool isBanlanced(BinarySearchTreeNode* root)
{
	if (root == nullptr)
	{
		return true;
	}
	int heiht_left = binaryTree_height(root->left);
	int heihet_right = binaryTree_height(root->right);
	if (abs(heihet_right - heiht_left) > 1)
	{
		return false;
	}
	/*if (abs(binaryTree_height(root->left) - binaryTree_height(root->right)) < 1)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return isBanlanced(root->left) && isBanlanced(root->right);
	
}
void test_isbalanced()
{
	int a[] = { 7,4,5,6,1,8,9 };
	//int a[] = { 1,2,3 };
	int lenght = sizeof(a) / sizeof(a[0]);

	BinarySearchTreeNode* root = nullptr;
	for (int i = 0; i < lenght; i++)
	{
		addNode(root, a[i]);
	}
	if (isBanlanced(root))
	{
		cout << "这棵树是平衡二叉树" << endl;
	}
	else
	{
		cout << "这棵树不是平衡二叉树" << endl;
	}
}
举报

相关推荐

0 条评论