树-链表-10.09

#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)
{
Node
p;
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值