针对插入到一个有序的单链表的小程序所做的调试

《C和指针》第12章-使用结构和指针

  针对插入到一个有序的单链表的小程序所做的调试:

  原理都是保存一个指向链表当前节点之前的那个节点的指针。

第一次:函数的参数是指向节点的指针

    问题:当插入到链表的起始位置时,需要修改根指针,但此时函数中的根指针只是原指针的一份拷贝,无法修改。可以通过将根指针声明为全局变量来修改它,但这样一来,这个函数只对这个链表起作用。

第二次:函数的参数是指向节点的指针的指针

    优点:将指向链表当前节点之前的节点指针初始化为NULL, 通过判断该指针是否为NULL来完善插入到链表起始位置的代码,这次程序可以修改指向起始节点的指针。

    问题:必须将插入到链表起始位置作为一种特殊情况。

第三次:把关注点放在需要修改的节点的next字段

    分析如下:

    typedef  struct Node

    {

    struct Node *next;               //注意这里next部分放在前面

            int data;

 }Node;

   需要修改的是某个节点的next段,因此要先保存它,然后指针指向下一个节点。

   Node **linkp;

   Node *current;

   linkp=&current->next;

   current=*linkp;

   这段代码中,*linkp是前一个节点的next字段内容,即下个节点的地址。当需要插入新节点时,只需将新节点的next指向current,然后将*linkp修改为这个新节点的地址。与之前的用一个previous指针保存之前节点的指针相比,优点就在于,不需要将起始位置作为特殊情况判断,因为*linkp本身就是指向第一个节点的指针,可以直接修改,而previous初始为NULL,无法取得previous->next.

以下为函数代码:

int sll_insert(Node **rootp,int value)
{
Node *front=*rootp;
Node *current;
Node *newNode;
while((current=*rootp)!=NULL&&current->data<value) //循环体简单,局部性好
rootp=&current->next;
newNode=(Node*)malloc(sizeof(Node));
if(newNode==NULL)
return false;
newNode->data=value;
newNode->next=current;
*rootp=newNode;
return true;
}

  总结:写出一个正确的程序不难,写出一个好的程序才需要实力。反复调试,精益求精。

posted @ 2012-03-13 11:08  shiney  阅读(999)  评论(2编辑  收藏  举报