#include<iostream>
#include<vector>
#include<string>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
typedef struct Node
{
char data;
struct Node *lchild, *rchild;
}*BiTree,BiTNode;
void CreatBiTree(BiTree &T)
{
char ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
T = new BiTNode;
T->data = ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
void InOrderTraverse(BiTree T)
{//中序遍历
if (T)
{
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
void PreOrderTraverse(BiTree T)
{//先序遍历
if (T)
{
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T)
{//后序遍历
if (T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data;
}
}
void Copy(BiTree T, BiTree &NewT)
{//二叉树的复制
if (T == NULL) {
NewT = NULL;
return;
}
else
{
NewT = new BiTNode;
NewT->data = T->data;
Copy(T->lchild, NewT->lchild);
Copy(T->rchild, NewT->rchild);
}
}
int Depth(BiTree T)
{//树的深度
if (T == NULL)
return 0;
else
{
int m = Depth(T->lchild);
int n = Depth(T->rchild);
if (m>n) return (m + 1);
else return (n + 1);
}
}
int NodeCount(BiTree T)
{//统计二叉树中结点的个数
if (T == NULL) return 0;
else return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}
int LeafCount(BiTree T)
{//统计二叉树中叶子结点的个数
if (!T) return 0;
if (!T->lchild && !T->rchild) {//如果二叉树左子树和右子树皆为空,说明该二叉树根节点为叶子节点,加1.
return 1;
}
else {
return LeafCount(T->lchild) + LeafCount(T->rchild);
}
}
int Node_1_Count(BiTree T)
{//统计二叉树的度为1的结点个数
if (!T) return 0;
if ((!T->lchild) && (T->rchild) || (T->lchild) && (!T->rchild))
return 1 + Node_1_Count(T->lchild) + Node_1_Count(T->rchild);
else
return Node_1_Count(T->lchild) + Node_1_Count(T->rchild);
}
void PrintAllPath(BiTree T, char path[], int pathlen)
{//二叉树中从每个叶子结点到根结点的路径
int i;
if (T != NULL) {
path[pathlen] = T->data; //将当前结点放入路径中
if (T->lchild == NULL && T->rchild == NULL) {//叶子结点
for (i = pathlen; i >= 0; i--)
cout << path[i] << " ";
cout << endl;
}
else {
PrintAllPath(T->lchild, path, pathlen + 1);
PrintAllPath(T->rchild, path, pathlen + 1);
}
}
}
void ExChangeTree(BiTree &T)
{//构造函数,使用递归算法进行左右结点转换
BiTree temp;
if (T != NULL) {//判断T是否为空,非空进行转换,否则不转换
temp = T->lchild;
T->lchild = T->rchild;//直接交换节点地址
T->rchild = temp;
ExChangeTree(T->lchild);
ExChangeTree(T->rchild);
}
}
void DblOrderTraverse(BiTree T)
{//二叉树的双序遍历
if (T)
{
cout << T->data;
DblOrderTraverse(T->lchild);
cout << T->data;//访问两遍
DblOrderTraverse(T->rchild);
}
}
int main()
{
BiTree T;
//测试例子AB#CD##E##F#GH###
cout << "先序遍历输入(以#结束):";
CreatBiTree(T);
cout << "中序遍历输出:";
InOrderTraverse(T);
cout << endl << "先序遍历输出:";
PreOrderTraverse(T);
cout << endl << "后序遍历输出:";
PostOrderTraverse(T);
cout << endl << "树的深度:" << Depth(T);
cout << endl << "结点的个数:" << NodeCount(T);
cout << endl << "叶结点的个数:" << LeafCount(T);
cout << endl << "度为1的结点个数:" << Node_1_Count(T);
cout << endl << "二叉树中从每个叶子结点到根结点的所有路径:" << endl;
char path[256];
int pathlen = 0;
PrintAllPath(T, path, pathlen);//
//交换二叉树每个结点的左孩子和右孩子
BiTree tem = T;//直接复制一颗树,在不改变原树的前提下,对临时树进行交换。
ExChangeTree(tem);
cout << "先序遍历输出交换后的结果:";
PreOrderTraverse(tem);
cout << endl << "双序遍历输出:";
DblOrderTraverse(T);
return 0;
}
判断二叉树是不是平衡树
·如果二叉树为空, 返回真
·如果二叉树不为空,如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1,返回真,其他返回假
bool IsAVLTree(TreeNode root)
{
if(root==null)
{
return true;
}
if(abs(getDepth(root.left)-getDepth(root.right))>1)
{
return false;
}
return IsAVLTree(root.left)&&IsAVLTree(root.right);
}
判断两个二叉树是否互相镜像
比较r1的左子树的镜像是不是r2的右子树
比较r1的右子树的镜像是不是r2的左子树
public static boolean isMirrorRec(TreeNode r1, TreeNode r2) {
if (r1 == null && r2 == null) {
return true;
} else if (r1 == null || r2 == null) {
return false;
}
if (r1.val != r2.val) {
return false;
}
// 递归比较r1的左子树的镜像是不是r2右子树
// 和r1的右子树的镜像是不是r2的左子树
return isMirrorRec(r1.left, r2.right) && isMirrorRec(r1.right, r2.left);
}
判断是否是二叉排序树
//判断是否为二叉排序树
bool Judge(BinaryTree* root,int& MAX){
if(root == NULL){//树为空则为二叉排序树
return true;
}
bool bst_l,bst_r;
bst_l = Judge(root->lchild,MAX);//判断左子树是否为二叉排序树
if(!bst_l || MAX >= root->data){
return false;
}
MAX = root->data;
bst_r = Judge(root->rchild,MAX);//判断右子树是否为二叉排序树
return bst_r;
}
两个节点的最近公共祖先:
·如果两个节点都比根节点小,则递归左子树 ;
·如果两个节点都比跟节点大,则递归右子树 ;
·否则,两个节点一个在左子树,一个在右子树,则当前节点就是最近公共祖先节点。
Node* GetAncestor(Node* root, Node* x1, Node* x2)//1.该二叉树为搜索二叉树
{
assert(x1 && x2);
if (x1->_data <= root->_data && x2->_data <= root->_data)
{
return GetAncestor(root->_left, x1, x2);//两个节都小于根节点,最近公共祖先在左子树中
}
else if (x1->_data > root->_data && x2->_data > root->_data)
{
return GetAncestor(root->_right, x1, x2);//两个节都大于根节点,最近公共祖先在左子树中
}
else
return root; //一个在左子树,一个在右子树,找到公共祖先
}
单链表:
#include
#include
#include
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
typedef struct Node
{
int data;
struct Node* next;
}Node,LinkedList;
//链表初始化
LinkedList LinkdeListInit()
{
Node L;
L = (Node)malloc(sizeof(Node));//申请节点空间
if (L == NULL)
cout << “申请空间失败” << endl;
L->next = NULL;
return L;
}
LinkedList LinkdeListCreat()
{
Node L;
int x;
L = (Node)malloc(sizeof(Node));
L->next = NULL;
while (cin>>x)
{
Nodep;
p = (Node*)malloc(sizeof(Node));
p->data = x;
p->next = L->next;
L->next = p;
if (cin.get()==’\n’)
{
break;
}
}
return L;
}
//单链表的建立2,尾插法建立单链表
LinkedList LinkedListCreatT()
{
Node *L;
L = (Node *)malloc(sizeof(Node)); //申请头结点空间
L->next = NULL; //初始化一个空链表
Node *r;
r = L; //r始终指向终端结点,开始时指向头结点
int x; //x为链表数据域中的数据
while (cin>>x)
{
Node *p;
p = (Node *)malloc(sizeof(Node)); //申请新的结点
p->data = x; //结点数据域赋值
r->next = p; //将结点插入到表头L-->|1|-->|2|-->NULL
r = p;
if (cin.get() == '\n')
{
break;
}
}
r->next = NULL;
return L;
}
//单链表的插入,在链表的第i个位置插入x的元素
LinkedList LinkedListInsert(LinkedList L, int i, int x)
{
Node*head = L;
Node *p;
p = (Node *)malloc(sizeof(Node)); //申请新的结点
int l = 0;
while (l != i)
{
head = head->next;
l++;
}
p->data = x;
p->next = head->next;
head->next = p;
return L;
}
//单链表的删除,在链表中删除值为x的元素
LinkedList LinkedListDelete(LinkedList L, int x)
{
Node *p; //pre为前驱结点,p为查找的结点。
Node *pre = NULL;
p = L->next;
while (p->data != x) //查找值为x的元素
{
pre = p;
p = p->next;
}
pre->next = p->next; //删除操作,将其前驱next指向其后继。
free(p);
return L;
}
/
int main()
{
LinkedList list, start;
cout << “请输入单链表的数据:” << endl;
list = LinkedListCreatT();
for (start = list->next; start != NULL; start = start->next)
cout << start->data << endl;
int i;
int x;
cout << “请输入插入数据的位置:” << endl;
cin >> i;
cout << “请输入插入数据的值:” << endl;
cin >> x;
LinkedListInsert(list, i, x);
for (start = list->next; start != NULL; start = start->next)
cout << start->data << endl;
cout << “请输入要删除的元素的值:” << endl;
cin >> x;
LinkedListDelete(list, x);
for (start = list->next; start != NULL; start = start->next)
cout << start->data << endl;
return 0;
}
从链表尾部添加节点:
LinkdeList AddToTail(LinkdeList L,int x)
{
Node p=new Node();
p->data=x;
if(L==NULL)
{
L=p;
}
else
{
Node*pcur=L;
while(pcur->next!=NULL)
{
pcur=pcur->next;
}
L->next=pcur;
}
return L;
}
删除链表节点:
ListNode *RemoveNode(ListNode **pHead, int data)
{
if (*pHead == NULL || pHead == NULL)
return NULL;
ListNode *pBeDelNode = NULL;
if ((*pHead)->m_data == data)
{
pBeDelNode = *pHead;
*pHead = (*pHead)->m_pNext;
}
else
{
ListNode *pNode = *pHead;
while (pNode->m_pNext != NULL && pNode->m_pNext->m_data != data)
{
pNode = pNode->m_pNext;
}
if (pNode->m_pNext != NULL && pNode->m_pNext->m_data == data)
{
pBeDelNode = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
}
if (pBeDelNode->m_pNext != NULL)
{
delete pBeDelNode;
pBeDelNode = NULL;
}
}
找出倒数第K个节点
//为了能够只遍历一次就能找到倒数第k个节点,可以定义两个指针:
//(1)第一个指针从链表的头指针开始遍历向前走k - 1,第二个指针保持不动;
//(2)从第k步开始,第二个指针也开始从链表的头指针开始遍历;
//(3)由于两个指针的距离保持在k - 1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。
ListNode *Find_K_Node(ListNode *pHead, int k)
{
if (pHead == NULL || k <= 0)
return NULL;
ListNode *pAhead = pHead;
ListNode *pBhend = pHead;
int i = 0;
for (int i = 0; i < (k - 1); i++)
{
if (pAhead->m_pNext == NULL)
return NULL;
pAhead = pAhead->m_pNext;
}
while (pAhead->m_pNext != NULL)
{
pAhead = pAhead->m_pNext;
pBhend = pBhend->m_pNext;
}
return pBhend;
}
反转链表:
https://www.cnblogs.com/GODYCA/archive/2012/12/27/2835185.html
1、迭代方法:
ListNode* ReverseNode(ListNode *pHead)
{
if (pHead == NULL)
return NULL ;
if (pHead->m_data == NULL)
return NULL ;
ListNode *pCurrNode = pHead;
ListNode *RetNode = NULL;
while (pCurrNode != NULL)
{
ListNode *pTemNode = pCurrNode->m_pNext; //指向当前节点的下一节点
pCurrNode->m_pNext = RetNode; //当前节点指向前一个节点
RetNode = pCurrNode; //前一节点指向当前节点
pCurrNode = pTemNode; //当前节点指向下一节点
}
return RetNode;
}
2、递归方法
ListNode *ReverseNode2(ListNode* pNode)
{
ListNode *pPerNode = pNode;
if (pNode->m_pNext == NULL)
return pNode;
else
{
ReverseNode2(pNode->m_pNext);
pNode->m_pNext->m_pNext = pNode;
if (pNode == pPerNode)
pPerNode->m_pNext = NULL;
}
}
从尾到头打印链表:
//思路:利用栈的特性,先进先出,后进后出。从头到尾部遍历链表保存到栈中,再从栈顶开始输出值
#include<stack>
void PrintListNode(ListNode *pNode)
{
std::stack<ListNode*>Node;
ListNode*pTemNode = pNode;
while (pTemNode != NULL)
{
Node.push(pTemNode);
pTemNode = pTemNode->m_pNext;
}
while (!Node.empty())
{
pTemNode = Node.top();
cout << pTemNode->m_data << endl;
Node.pop();
}
}
合并两个有序链表
ListNode *MergeNode(ListNode *pNodeA, ListNode*pNodeB)
{
if (pNodeA == NULL || pNodeB == NULL)
return NULL;
ListNode *NewNode = new ListNode();
ListNode *RetNode = NewNode;
while (pNodeA != NULL && pNodeB != NULL)
{
if (pNodeA->m_data < pNodeB->m_data)
{
NewNode = pNodeA;
pNodeA = pNodeA->m_pNext;
}
else
{
NewNode = pNodeB;
pNodeB = pNodeB->m_pNext;
}
NewNode = NewNode->m_pNext;
}
//其中一个还有剩余字节的链表接在新链表的后面就可以了
if (pNodeA != NULL)
NewNode->m_pNext = pNodeA;
if (pNodeB != NULL)
NewNode->m_pNext = pNodeB;
return NewNode;
}
判断链表是否有环
https://www.cnblogs.com/dancingrain/p/3405197.html
bool FindLoopNode(ListNode *pNode)
{
if (pNode == NULL)
return NULL;
ListNode *pFast, *pSlow;
pFast = pSlow = pNode;
while (pSlow != NULL && pFast->m_pNext != NULL)
{
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext->m_pNext;
if (pSlow == pSlow)
return true;
}
return false;
}