面试高频题:单链表的逆置操作/链表逆序

 函数内对形参的操作并不能影响实参,函数内修改的是实参的副本。要想在函数内部修改输入参数,要么传入的是实参的引用,要么传入的是实参的地址。


#include <iostream>

#include <cstdlib>

#include <cstring>//strlen

using namespace std;

//template <class T>

class node

{

      public:

          node * next;

          char data;

};

node *node_reverse(node *head)

{

    //如果一个函数的输入参数有指针,一定要记住判断指针时候为空

    //1>:在使用一个指针之前一定要判断它是否为空;

    //2>:使用完后要释放由指针指向的存储单元

    //3>:释放完存储单元后要将指针赋值为NULL;

     if(head->next==NULL || head==NULL)

          return head;







     node* pPre=head;    //先前指针

     node* pCurrent=pPre->next;  //当前指针

     node* pNext=NULL;       //后继指针

     //要注意这里面的顺序,先将pNext保存在pCurrent中,

     //然后再将pNext移动到下一个元素,然后才能改动pCurrent

     //

     while(pCurrent!=NULL)

     {

        pNext=pCurrent->next;

        pCurrent->next=pPre;

        pPre=pCurrent;

        pCurrent=pNext;



     }

     head->next=NULL;

     head=pPre;

     return head;

}

/**************

void init_node(node *tail,char *init_array)

这样声明函数是不正确的,函数的原意是通过数组初始化链表

若链表结点传入的是指针,则并不能创建链表,除非是二维指针

即指向指针的指针

****************/

void init_node_by_referenceToPointer(node *&tail,const char *init_array)

{

     node * tmp = NULL;

     int j=strlen(init_array);

     for(int i=0; i<j; i++)

     {

         tmp = new node;

         tmp->data = *(init_array+i);

         tmp->next = tail;

         tail = tmp;

     }

}

/***************************************

void init_node_by_referenceToPointer(node &*tail,char *init_array)

error: cannot declare pointer to 'class node&'

****************************************/

void init_node_by_pointerToPointer(node **tail,const char *init_array)

{

     node * tmp = NULL;

     int j=strlen(init_array);

     for(int i=0; i<j; i++)

     {

         tmp = new node;

         tmp->data = *(init_array+i);

         tmp->next = *tail;

         *tail = tmp;

     }

}

void display(node *nn,char *print=NULL)

{

    if(nn==NULL)

    {

        cout << "no data to display\n";

        return ;

    }

    cout<<print;

    node *dis = nn;

    while(dis!=NULL)

    {

        cout << dis->data;

        dis = dis->next;

    }

}



//释放动态申请的空间

void distroy(node *nn)

{

    if (nn==NULL)

    {

        return ;

    }

    while (nn!=NULL)

    {

        node *tmp = nn;

        nn = nn->next;

        delete tmp;

    }

}





void test_by_referenceToPointer()

{

    node *test = NULL;

    char *test_array="wang_shi_hui";

    init_node_by_referenceToPointer(test,test_array);

    //如果输入参数是指向指针的引用

    display(test,"单链表逆置前\n");

    cout << "\n init_node_by_referenceToPointer" << endl;

    node *tmp = node_reverse(test);

    if(test==NULL)

        exit(0);

    display(tmp,"单链表逆置后\n");

    //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!

    //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~

    distroy(tmp);//释放动态申请的内存

    tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~

    test = NULL;

    cout << "\n after destory tmp= " << tmp << endl;



    //如果上面没有tmp = NULL;test = NULL;,display将会出错,

    //因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,

    //那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,

    //这样就会出现异常.

    display(test);



}

void test_by_pointerToPointer()

{

    node *test = NULL;

    char *test_array="123456789";

    init_node_by_pointerToPointer(&test,test_array);

    //如果输入参数是指向指针的指针

    display(test,"单链表逆置前\n");

    cout << "\n init_node_by_pointerToPointer" << endl;

    node *tmp = node_reverse(test);

    if(test==NULL)

        exit(0);

    display(tmp,"单链表逆置后\n");

    //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!

    //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~

    distroy(tmp);//释放动态申请的内存

    tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~

    test = NULL;

    cout << "\n after destory tmp= " << tmp << endl;



    //如果上面没有tmp = NULL;test = NULL;,display将会出错,

    //因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,

    //那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,

    //这样就会出现异常.

    display(test);



}

int main()

{

    test_by_referenceToPointer();

    cout<<"\n---------------------\n";

    test_by_pointerToPointer();

}

/************************************************

单链表逆置前

iuh_ihs_gnaw

 init_node_by_referenceToPointer

单链表逆置后

wang_shi_hui

 after destory tmp= 0

no data to display



---------------------

单链表逆置前

987654321

 init_node_by_pointerToPointer

单链表逆置后

123456789

 after destory tmp= 0

no data to display

*************************************************/



你可能感兴趣的:(单链表)