上一篇 | 下一篇

C语言教程4-2

发布: 2008-6-26 21:02 | 作者: admin | 来源: | 查看: 0次

[例7.12]写一个函数,删除链表中的指定结点。删除一个结点有两种情况:

1. 被删除结点是第一个结点。这种情况只需使head指向第二个结点即可。即head=pb->next。其过程如图7.5所示。

2. 被删结点不是第一个结点,这种情况使被删结点的前一结点指向被删结点的后一结点即可。即pf->next=pb->next。其过程如图7.6所示。

函数编程如下:

TYPE * delete(TYPE * head,int num)

{

TYPE *pf,*pb;

if(head==NULL) /*如为空表, 输出提示信息*/

{ printf("\nempty list!\n");

goto end;}

pb=head;

while (pb->num!=num && pb->next!=NULL)

/*当不是要删除的结点,而且也不是最后一个结点时,继续循环*/

{pf=pb;pb=pb->next;}/*pf指向当前结点,pb指向下一结点*/

if(pb->num==num)

{if(pb==head) head=pb->next;

/*如找到被删结点,且为第一结点,则使head指向第二个结点,

否则使pf所指结点的指针指向下一结点*/

else pf->next=pb->next;

free(pb);

printf("The node is deleted\n");}

else

printf("The node not been foud!\n");

end:

return head;

}

  函数有两个形参,head为指向链表第一结点的指针变量,num删结点的学号。 首先判断链表是否为空,为空则不可能有被删结点。若不为空,则使pb指针指向链表的第一个结点。进入while语句后逐个查找被删结点。找到被删结点之后再看是否为第一结点,若是则使head指向第二结点(即把第一结点从链中删去),否则使被删结点的前一结点(pf所指)指向被删结点的后一结点(被删结点的指针域所指)。如若循环结束未找到要删的结点, 则输出“末找到”的提示信息。最后返回head值。

[例7.13]写一个函数,在链表中指定位置插入一个结点。在一个链表的指定位置插入结点, 要求链表本身必须是已按某种规律排好序的。例如,在学生数据链表中, 要求学号顺序插入一个结点。设被插结点的指针为pi。 可在三种不同情况下插入。

1. 原表是空表,只需使head指向被插结点即可。见图7.7(a)

2. 被插结点值最小,应插入第一结点之前。这种情况下使head指向被插结点,被插结点的指针域指向原来的第一结点则可。即:pi->next=pb;

head=pi; 见图7.7(b)

3. 在其它位置插入,见图7.7(c)。这种情况下,使插入位置的前一结点的指针域指向被插结点,使被插结点的指针域指向插入位置的后一结点。即为:pi->next=pb;pf->next=pi;

4. 在表末插入,见图7.7(d)。这种情况下使原表末结点指针域指向被插结点,被插结点指针域置为NULL。即:

pb->next=pi;

pi->next=NULL; TYPE * insert(TYPE * head,TYPE *pi)

{

TYPE *pf,*pb;

pb=head;

if(head==NULL) /*空表插入*/

(head=pi;

pi->next=NULL;}

else

{

while((pi->num>pb->num)&&(pb->next!=NULL))

{pf=pb;

pb=pb->next; }/*找插入位置*/

if(pi->num<=pb->num)

{if(head==pb)head=pi;/*在第一结点之前插入*/

else pf->next=pi;/*在其它位置插入*/

pi->next=pb; }

else

{pb->next=pi;

pi->next=NULL;} /*在表末插入*/

}

return head;}

  本函数有两个形参均为指针变量,head指向链表,pi 指向被插结点。函数中首先判断链表是否为空,为空则使head指向被插结点。表若不空,则用while语句循环查找插入位置。找到之后再判断是否在第一结点之前插入,若是则使head 指向被插结点被插结点指针域指向原第一结点,否则在其它位置插入, 若插入的结点大于表中所有结点,则在表末插入。本函数返回一个指针, 是链表的头指针。 当插入的位置在第一个结点之前时, 插入的新结点成为链表的第一个结点,因此head的值也有了改变, 故需要把这个指针返回主调函数。

[例7.14]将以上建立链表,删除结点,插入结点的函数组织在一起,再建一个输出全部结点的函数,然后用main函数调用它们。

#define NULL 0

#define TYPE struct stu

#define LEN sizeof(struct stu)

struct stu

{

int num;

int age;

struct stu *next;

};

TYPE * creat(int n)

{

struct stu *head,*pf,*pb;

int i;

for(i=0;i

{

pb=(TYPE *)malloc(LEN);

printf("input Number and Age\n");

scanf("%d%d",&pb->num,&pb->age);

if(i==0)

pf=head=pb;

else pf->next=pb;

pb->next=NULL;

pf=pb;

}

return(head);

}

TYPE * delete(TYPE * head,int num)

{

TYPE *pf,*pb;

if(head==NULL)

{ printf("\nempty list!\n");

goto end;}

pb=head;

while (pb->num!=num && pb->next!=NULL)

{pf=pb;pb=pb->next;}

if(pb->num==num)

{ if(pb==head) head=pb->next;

else pf->next=pb->next;

printf("The node is deleted\n"); }

else

free(pb);

printf("The node not been found!\n");

end:

return head;

}

TYPE * insert(TYPE * head,TYPE * pi)

{

TYPE *pb ,*pf;

pb=head;

if(head==NULL)

{ head=pi;

pi->next=NULL; }

else

{

while((pi->num>pb->num)&&(pb->next!=NULL))

{ pf=pb;

pb=pb->next; }

if(pi->num<=pb->num)

{ if(head==pb) head=pi;

else pf->next=pi;

pi->next=pb; }

else

{ pb->next=pi;

pi->next=NULL; }

}

return head;

}

void print(TYPE * head)

{

printf("Number\t\tAge\n");

while(head!=NULL)

{

printf("%d\t\t%d\n",head->num,head->age);

head=head->next;

}

}

main()

{

TYPE * head,*pnum;

int n,num;

printf("input number of node: ");

scanf("%d",&n);

head=creat(n);

print(head);

printf("Input the deleted number: ");

scanf("%d",&num);

head=delete(head,num);

print(head);

printf("Input the inserted number and age: ");

pnum=(TYPE *)malloc(LEN);

scanf("%d%d",&pnum->num,&pnum->age);

head=insert(head,pnum);

print(head);

}

  本例中,print函数用于输出链表中各个结点数据域值。函数的形参head的初值指向链表第一个结点。在while语句中,输出结点值后,head值被改变,指向下一结点。若保留头指针head, 则应另设一个指针变量,把head值赋予它,再用它来替代head。在main函数中,n为建立结点的数目, num为待删结点的数据域值;head为指向链表的头指针,pnum为指向待插结点的指针。 main函数中各行的意义是:

第六行输入所建链表的结点数;

第七行调creat函数建立链表并把头指针返回给head;

第八行调print函数输出链表;

第十行输入待删结点的学号;

第十一行调delete函数删除一个结点;

第十二行调print函数输出链表;

第十四行调malloc函数分配一个结点的内存空间, 并把其地址赋予pnum;

第十五行输入待插入结点的数据域值;

第十六行调insert函数插入pnum所指的结点;

第十七行再次调print函数输出链表。

字号: | 推荐给好友

42/4<1234>

评分:0

我来说两句