二叉树的高度 、销毁、链表的翻转(k为一组、n-m 之间)两种实现、

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值