习题11-7 奇数值结点链表(二级指针)
这道题真的好难啊,必须要好好看看指针的内容了!!!
函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到-1时表示输入结束,函数应返回指向单链表头结点的指针----考察尾插法建立链表。
从题目中的printlist函数可以看出,传入的链表是不带头结点的,但是下面的两个函数我都写成带头结点的链表,但是函数返回的时候没有返回头结点指针。
1 struct ListNode *readlist() { 2 int temp; 3 struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode)),*r;//尾插法建立带头结点的链表head 4 head->next = NULL; 5 r = head; 6 while(scanf("%d",&temp)) { 7 if(temp == -1)//输入-1时,结束 8 break; 9 struct ListNode* p = (struct ListNode*)malloc(sizeof(struct ListNode)); 10 p->data = temp; 11 p->next = NULL; //每次开辟一个结构体空间,记得让 next 指向NULL 12 r->next = p; 13 r = p; 14 } 15 return head->next; 16 }
函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。------考察二级指针变量作为函数参数时,修改二级指针中存放的一级指针。
1 struct ListNode *getodd(struct ListNode **L) { 2 struct ListNode *Odd = (struct ListNode*)malloc(sizeof(struct ListNode)),*r;//尾插法建立带头结点的链表Odd,用于记录所有奇数结点 3 Odd->next = NULL; 4 r = Odd; 5 6 struct ListNode *p = *L; //取一级指针,一级指针指向 链表的第一个结点 7 struct ListNode *pre = (struct ListNode *)malloc(sizeof(struct ListNode));//删除一个结点,必须要知道其前驱结点 8 pre->next = p; 9 int flag = 0; 10 while(p != NULL) { 11 if(p->data%2 == 1) {//奇数 12 r->next = p; //可以不开启新的空间,只需改变指针指向来连接起 Odd链表 13 r = p; 14 p = p->next; 15 pre->next = p; 16 } else { 17 if(flag == 0) {//第一次出现偶数 18 *L = p; //修改二级指针中的一级指针,不能写成了 L = &p,可以参考下面的swap()函数; 19 flag = 1; 20 } 21 pre = p; 22 p = p->next; 23 } 24 } 25 r->next = NULL; //Odd链表的末尾结点指向NULL 26 if(flag == 0) *L = NULL; //全是奇数的情况 27 return Odd->next; 28 }

1 #include<iostream> 2 using namespace std; 3 4 void swap1(int *a,int *b) { //交换一级指针中的基本变量 5 int temp = *a; 6 *a = *b; 7 *b = temp; 8 } 9 10 void swap2(int **a,int **b) { //交换二级指针中的一级指针 11 int* temp = *a; 12 *a = *b; 13 *b = temp; 14 } 15 int main() { 16 int a = 5,b = 10; 17 int *p1 = &a,*p2 = &b; 18 swap1(p1,p2); 19 printf("%d %d\n",*p1,*p2); 20 int **pp1 = &p1,**pp2 = &p2; 21 swap2(pp1,pp2); 22 printf("%d %d",**pp1,**pp2); 23 return 0; 24 }


浙公网安备 33010602011771号