1.二叉树的高度:
//实现思路:左右子树较高的一支,将其结果结+1就是当前树的高度
size_t GetHeight(Node* pRoot)
{
if (pRoot)
{
size_t left = GetHeight(pRoot->pLeft);
size_t right= GetHeight(pRoot->pRight);
return left > right ? left + 1 : right + 1;
}
2.二叉树的销毁
//实现思路:后序遍历,进行销毁
void Destroy(Node*& pRoot) //参数最好给引用,方便直接修改外部参数为NULL
{
if (pRoot)
{
Destroy(pRoot->pLeft);
Destroy(pRoot->pRight);
delete pRoot;
pRoot = NULL;
}
}
3.链表的翻转(以k为一组)
//以K为单位翻转链表
//思路:两种实现思路:1.递归法2.迭代法
//递归出口,如果链表长度小于
//实现区间内的链表翻转,并且返回翻转后的头结点
//内部调用自己,将返回结果善加利用
Node* reversekGroup1(Node* head, int k)
{
if (head == NULL || head->pNext == NULL || k < 2)
{
return head;
}
Node* next_group = head;
for (int i = 1; i < k; i++) //走k-1步
{
if (next_group)
{
next_group = next_group->pNext;
}
else
{
return head; //长度小于K ,直接返回头结点
}
}
Node* new_next_group = reversekGroup1(next_group,k);//返回下一组的头结点
Node* prev = NULL, *cur = head;
while (cur != next_group)// 实现翻转:翻转三要素:三个指针,保存下一个指针,就可以自由操作了
{
Node* next = cur->pNext;
cur->pNext = prev ? prev : new_next_group;
prev = cur;
cur = next;
}
return prev; //prev will be the new head of this group
}
//prev为 first的前一个元素,[begin ,end] 闭区间,保证三者都不为NULL
//返回翻转后的倒数第一个元素
//实现翻转
Node* reverse(Node* prev, Node* begin, Node* end)
{
Node* end_next =end->pNext;
for (Node* p = begin, *cur = p->pNext, *next = cur->pNext;
cur != end_next;
p = cur, cur = next, next = next ? next->pNext : NULL
)
{
cur->pNext = p;
}
begin->pNext = end_next;
prev->pNext = end;
return begin;
}
//迭代法:思路:每K个区间翻转一次,实现整体翻转
Node* reversekGroup2(Node* head, int k)
{
if (head == NULL || head->pNext == NULL || k < 2)
{
return head;
}
Node dummy(-1); //因为头结点会发生改变,所以虚拟头结点可以有效的解决该问题
dummy.pNext = head;
for (Node* prev = &dummy, *end = head; end; end = prev->pNext)
{
//每K个划分为一组
for (int i = 0; i < k&&end; i++)
{
end = end->pNext;
}
if (end == NULL)
{
break; //不足K个
}
prev = reverse(prev,prev->pNext,end);
}
return dummy.pNext;
}
void Test1()
{
Node* node1 = new Node(1);
Node* node2 = new Node(2);
Node* node3 = new Node(3);
Node* node4 = new Node(4);
Node* node5 = new Node(5);
Node* node6 = new Node(6);
Node* node7 = new Node(7);
Node* node8 = new Node(8);
Node* node9 = new Node(9);
Node* node10 = new Node(10);
node1->pNext = node2;
node2->pNext = node3;
node3->pNext = node4;
node4->pNext = node5;
node5->pNext = node6;
node6->pNext = node7;
node7->pNext = node8;
node8->pNext = node9;
node9->pNext = node10;
//ReverseEveryKth(node1, 2);
//reverBetween(node1,2,4);
Print(node1);
cout << endl;
/*Node* temp=reversekGroup1(node1, 3);
Print(temp);
cout << endl;*/
Node* temp = reversekGroup2(node1, 3);
Print(temp);
}
4.链表的翻转(n-m之间)
//将n-m之间的元素进行翻转
//头插法实现
Node* reverBetween(Node* head, int m, int n)
{
Node dummy(-1);
dummy.pNext = head;
Node* prev = &dummy;
for (int i = 0; i < m; i++)
{
prev = prev->pNext;
}
Node* head2 = prev;
prev = head2->pNext;
Node* cur = prev->pNext;
for (int i = m; i < n; i++)
{
//头插法
//三步翻转法(头结点始终不变,插入到头的下一个结点)
prev->pNext = cur->pNext;
cur->pNext = head2->pNext;
head2->pNext = cur; //头插法
cur = prev->pNext;
}
return dummy.pNext;
}