本文参考该作者文章当作编程笔记: 作者:Hawstein 出处:http://hawstein.com/posts/ctci-solutions-contents.html
Q:
实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针。
例子:
输入:指向链表a->b->c->d->e中结点c的指针
结果:不需要返回什么,得到一个新链表:a->b->d->e
思路:
int removeNode(link):将后一个点删除,将后一个节点的数据复制到该点。需要注意节点C是不是头节点,尾节点。
Talk is cheap,Show me CODE:
接口 lish.h:
1 typedef struct node *link; 2 typedef int itemType;//将itemType设为int型 3 struct node{itemType item;link next;}; 4 void initNodes(struct node **);//初始化头节点 5 link newNode(itemType); 6 void insertNext(link,link);//在头节点后插入新节点 7 link deleteNext(link);//删除下一个节点 8 link Next(link);//返回下一个节点 9 itemType Item(link);//返回该节点的数据 10 void freeNode(link);//释放节点
实现 list.c
1 #include<stdlib.h> 2 #include"list.h" 3 void initNodes(struct node **head) 4 { 5 *head=malloc(sizeof(struct node)); 6 (*head)->next=NULL; 7 } 8 link newNode(itemType i) 9 { 10 link x=malloc(sizeof(struct node)); 11 x->item=i;x->next=NULL; 12 return x; 13 } 14 void insertNext(link x,link t) 15 { 16 t->next=x->next; 17 x->next=t; 18 } 19 link deleteNext(link x) 20 { 21 link t=x->next;x->next=t->next; 22 return t; 23 } 24 link Next(link x) 25 { 26 return x->next; 27 } 28 itemType Item(link x) 29 { 30 return x->item; 31 } 32 void freeNode(link x) 33 { 34 if(x!=NULL) 35 free(x); 36 }
客户 :
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include"list.h" 4 #define N 10 5 int removeNode(link c) 6 { 7 if(c==NULL || Next(c)==NULL)return 0; 8 link t=deleteNext(c); 9 c->item=Item(t); 10 freeNode(t); 11 return 1; 12 } 13 void printNodes(link h) 14 { 15 link p=h; 16 while((p=Next(p))!=NULL) 17 { 18 printf("%d ",Item(p)); 19 } 20 printf(" "); 21 } 22 int main() 23 { 24 int s[N]={1,2,3,4,5,6,7,8,9,0}; 25 struct node *head; 26 initNodes(&head); 27 int i; 28 for(i=0;i<N;i++) 29 insertNext(head,newNode(s[i])); 30 i=4; 31 link p=head; 32 while(--i>0) 33 p=Next(p); 34 if(removeNode(p)==1) 35 printNodes(head); 36 return 0; 37 }
问题:
- 带头节点的单链表,如果要删除的是头节点,这个程序是有问题的,它会删除头节点之后的节点,并将数据复制到头节点中。但显示的时候,程序是跳过头节点显示的。
- 指针和链表操纵的有问题,需要深入学习。