关于链式有序表的合并判断终结点问题
在最近复习数据结构的过程中对链式有序表的合并算法产生了一些疑问,并通过代码验证解决了这一问题。
1.首先将算法代码贴出
1 #include <iostream> 2 using namespace std; 3 4 typedef int ElemType; 5 6 //1.定义存储表示 7 typedef struct LNode 8 { 9 ElemType data; //数据域 10 struct LNode* next; //指针域 11 }LNode, * LinkList; 12 13 //2.初始化线性表La,Lb,Lc 14 void InitList_L(LinkList& La, LinkList& Lb, LinkList& Lc) 15 { 16 La = new LNode; 17 La->next = NULL; 18 19 Lb = new LNode; 20 Lb->next = NULL; 21 22 Lc = new LNode; 23 Lc->next = NULL; 24 cout << "线性表初始化成功\n\n" << endl; 25 26 } 27 28 //3.建立单链表 29 void CreateList_R(LinkList& La, LinkList& Lb, int q, int t) 30 { 31 LinkList m; 32 La = new LNode; 33 La->next = NULL; 34 LinkList r = La; 35 36 for (int i = 0; i < q; ++i) 37 { 38 m = new LNode; 39 cout << "请输入La第" << i + 1 << "个所要创建的数据元素内容" << endl; 40 cin >> m->data; 41 m->next = NULL; 42 r->next = m; 43 r = m; 44 } 45 46 LinkList n; 47 Lb = new LNode; 48 Lb->next = NULL; 49 LinkList e = Lb; 50 51 for (int i = 0; i < t; ++i) 52 { 53 n = new LNode; 54 cout << "请输入Lb第" << i + 1 << "个所要创建的数据元素内容" << endl; 55 cin >> n->data; 56 n->next = NULL; 57 e->next = n; 58 e = n; 59 } 60 61 } 62 63 64 //合并有序链表 65 void MergeList_L(LinkList& La, LinkList& Lb, LinkList& Lc) 66 { 67 LinkList pa; 68 LinkList pb; 69 LinkList pc; 70 pa = La->next; 71 pb = Lb->next; 72 Lc = pc = La; 73 74 while (pa && pb) 75 { 76 if (pa->data <= pb->data) 77 { 78 pc->next = pa; 79 pc = pa; 80 pa = pa->next; 81 } 82 else 83 { 84 pc->next = pb; 85 pc = pb; 86 pb = pb->next; 87 } 88 } 89 90 91 92 pc->next = pa ? pa:pb; 93 delete Lb; 94 } 95 96 97 //显示单链表 98 void DisplayList(LinkList L) 99 { 100 LinkList p = L->next; 101 102 while (p) 103 { 104 cout << p->data << ","; 105 p = p->next; 106 } 107 } 108 109 int main() 110 { 111 LinkList La; 112 LinkList Lb; 113 LinkList Lc; 114 InitList_L(La, Lb, Lc); 115 116 int q; 117 int t; 118 119 cout << "请输入你所要在La创建的数据元素个数" << endl; 120 cin >> q; 121 122 cout << "请输入你所要在Lb创建的数据元素个数" << endl; 123 cin >> t; 124 CreateList_R(La, Lb, q, t); 125 126 MergeList_L(La, Lb, Lc); 127 cout << "La,Lb的合并结果Lc为: " << endl; 128 DisplayList(Lc); 129 130 system("pause"); 131 return 0; 132 }
2.问题的发现:
在我逐行理解代码的过程中对92行的代码十分不解,根据我一开始的个人理解它的意思为判断
pc->next是否等于pa若等于则返回pa否则返回pb。但这种理解在我一步步调试中发现并不准确例如
若La中的数字全小于Lb,当La到达最后结点时pc的next一定与pa相等且为NULL这时若按照我的理解
则返回pa这明显大错特错。
3.问题的解决:
在几个小时的困恼后我忽然发现这个语句可能并不是单纯的判断相等语句而是一个赋值后判断是否
为空的语句;详细点说就是先将pa赋值给pc->next之后的?代表判断pc->next=pa是否为NULL,若为空则
语句pc->next=pa? pa:pb可简化为0?pa:pb则返回pb否则返回pa;这种理解方式明显既符合语句定义同
时有能得出正确结果。
4.思路的验证:
在得到这种思路后我对自己的想法进行了验证,方法就是在92行之前添加一段代码(如下)并创建一个以
La先到达最终结点的例子即可
1 if ((pc->next = pa) == NULL) 2 { 3 cout << "为空"<< endl; 4 }