C/C++面试之算法系列--典型的几个链表操作-逆序和重排

 

已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)

Node * ReverseList(Node *head) //链表逆序

{

if ( head == NULL || head->next == NULL ) // 否则下面的就错了,一定要注意一些特定条件的判断,边界问题狠重要,软件开发要注意对异常分支的处理

 

        // 三个指针的方式结构比较清晰

        Node *p1 = head;

        Node *p2 = p1->next;

        Node *p3 = p2->next;

        p1->next = NULL;

 

        while ( p3 != NULL )

        {

                p2->next = p1; // p2->nextp3,已经保存过了

                //p1p2p3都向前移动一个

                p1 = p2;

                p2 = p3;

                p3 = p3->next;

        }

 

        p2->next = p1; //最末端节点挂在链上

        head = p2;

 

        return head;

}

 

已知两个链表head1 head2 各自有序升序排列,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同

Node * Merge(Node *head1 , Node *head2)

{

        if ( head1 == NULL)

        return head2;

        if ( head2 == NULL)

        return head1;

 

        // 良好的习惯,指针要初始化为NULL

        Node *head = NULL;

        Node *p1 = NULL;

        Node *p2 = NULL;

 

        // 从小到大,获得头节点

        if ( head1->data =< head2->data )

        {

                head = head1;

                p1 = head1->next;    // 注意更新的不一样

                p2 = head2;

        }

        else

        {

                head = head2;

                p2 = head2->next;

                p1 = head1;

        }

 

        Node *pcurrent = head;

        while ( p1 != NULL && p2 != NULL)

        {

                if ( p1->data <= p2->data )

                {

                       pcurrent->next = p1; // 挂接新节点

                       pcurrent = p1; //更新当前最后一个节点

                       p1 = p1->next; //更新下一个待比较节点

                }

                else

                {

                       pcurrent->next = p2;

                       pcurrent = p2;

                       p2 = p2->next;

                }

        }

 

        if ( p1 != NULL ) //挂接剩余部分

        pcurrent->next = p1;

        if ( p2 != NULL )

        pcurrent->next = p2;

 

        return head;

}

 

 

已知两个链表head1 head2 各自升序排列,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk)

递归版本实际上很容易从上面一个版本改动而得来,主要是注意退出的条件和跌代的条件。

 

Node * MergeRecursive(Node *head1 , Node *head2)

{//退出条件是某链结束

        if ( head1 == NULL )

        return head2;

        if ( head2 == NULL)

        return head1;

 

        Node *head = NULL;

        if ( head1->data < head2->data )

        {

                head = head1;

                head->next = MergeRecursive(head1->next,head2);

        }

        else

        {

                head = head2;

                head->next = MergeRecursive(head1,head2->next);

        }

 

        return head;

}

 

你可能感兴趣的:(C/C++面试之算法系列--典型的几个链表操作-逆序和重排)