1 建立链表(带哨兵位的)
2 建立最小堆方法
3 合并已排好序的k个链表
1 typedef int DataType; 2 //建立链表 3 class Link 4 { 5 private: 6 struct Node 7 { 8 DataType data; 9 Node *next; 10 }; 11 Node *head; //哨兵位 12 public: 13 Link() 14 { 15 Init(); 16 } 17 ~Link() 18 { 19 Delete(); 20 } 21 void Init() 22 { 23 head = new Node; 24 head->next = NULL; 25 } 26 void Delete() 27 { 28 for (Node *p = head; p != NULL;) 29 { 30 Node *pTemp = p->next; 31 delete p; 32 p = pTemp; 33 } 34 head = NULL; 35 } 36 bool Empty() 37 { 38 return head->next == NULL; 39 } 40 void Print() 41 { 42 for (Node *p = head->next; p != NULL; p = p->next) 43 { 44 cout << p->data << endl; 45 } 46 } 47 //顺序插入 考虑两种情况 1.空表 2.当插入值是最大值的时候 48 void SortInsert(DataType data) 49 { 50 Node *p = head; 51 do 52 { 53 if (p->next == NULL || p->next->data > data) 54 { 55 Node *pNew = new Node; 56 pNew->data = data; 57 pNew->next = p->next; 58 p->next = pNew; 59 60 return; 61 } 62 p = p->next; 63 } while (true); 64 } 65 //使用数组初始化列表 66 void ArrayInsert(DataType array[], int size) 67 { 68 for (int i=0; i<size; ++i) 69 { 70 SortInsert(array[i]); 71 } 72 } 73 //尾插法直接插入 74 void Insert(DataType data) 75 { 76 Node *p = head; 77 while(p->next != NULL) 78 { 79 p = p->next; 80 } 81 82 Node *pNew = new Node; 83 pNew->data = data; 84 pNew->next = NULL; 85 p->next = pNew; 86 } 87 //去掉首结点并返回首结点的值 88 int ExtractDate() 89 { 90 if (! Empty()) 91 { 92 DataType data = head->next->data; 93 Node *p = head->next; 94 Node *pFirst = p->next; 95 96 delete p; 97 p = NULL; 98 99 head->next = pFirst; 100 return data; 101 } 102 return -1; 103 } 104 int GetData() 105 { 106 if (!Empty()) 107 { 108 return head->next->data; 109 } 110 } 111 bool Find(const DataType data) 112 { 113 for (Node *p = head->next; p != NULL; p = p->next) 114 { 115 if (p->data == data) 116 { 117 return true; 118 } 119 } 120 return false; 121 } 122 void Swap(Link &p) //交换两个链表主要是交换 head 123 { 124 if (head != p.head) 125 { 126 Node *tmp = head->next; 127 head->next = p.head->next; 128 p.head->next = tmp; 129 } 130 } 131 }; 132 //保持最小堆性质 参数inode为内部结点 注意结点从1开始,数组从0开始 133 void MinHeapify(int array[], int size, int inode) 134 { 135 int least= inode; //父结点 136 int left = inode*2; //左子结点 137 int right = inode*2+1; //右子结点 138 139 if (left <= size && array[left-1] < array[least-1]) 140 { 141 least = left; 142 } 143 if (right <= size && array[right-1] < array[least-1]) 144 { 145 least = right; 146 } 147 148 if (least != inode) //父结点小于 左子结点 或者 右子结点 149 { 150 int temp = array[inode-1]; //子结点值与父结点值交换 151 array[inode-1] = array[least-1]; 152 array[least-1] = temp; 153 154 MinHeapify(array, size, least); //再次验证被交换的值的子结点是否满足 最小堆性质 155 } 156 } 157 //建立最小堆 使每一个父结点小于子结点 158 void BuildMinHeap(int array[],int size) 159 { 160 for(int i=size/2; i>0; --i) //最多有 size/2 个内部结点 161 { 162 MinHeapify(array, size, i); 163 } 164 } 165 //k个已排好序的链表合并为一个链表 166 //pLink 链表数组的地址, linkSize链表数组的大小, array 数组的地址, count数组的大小 167 void SortLink(Link *pLink, int linkSize, Link *link) 168 { 169 int *pArray = new int[linkSize]; //动态分配k个大小的数组 170 for (int i=0; i<linkSize; ++i) //从k个链表中取首结点的值 171 { 172 pArray[i] = pLink[i].GetData(); 173 } 174 175 int j=0; 176 do 177 { 178 BuildMinHeap(pArray,linkSize); //构造最小堆,即每个父结点小于或等于子结点,根结点为最小值 179 for (j=0; j<linkSize; ++j) 180 { 181 if(pLink[j].Find(pArray[0])) //寻找最小值来自于哪一个链表 182 { 183 link->Insert(pLink[j].ExtractDate()); //去掉并返回链表的的值(更新链表) 184 break; 185 } 186 } 187 if (!pLink[j].Empty()) //确保取出值的链表不为空 188 { 189 pArray[0] = pLink[j].GetData(); //更新数组 190 } 191 else 192 { 193 pArray[0] = pArray[linkSize-1]; 194 pLink[j].Swap(pLink[linkSize-1]); //交换两个链表 195 --linkSize; 196 } 197 } while (linkSize != 0); 198 199 delete [] pArray; 200 } 201 void main() 202 { 203 //检测是否有内存泄露 需要加头文件#include <crtdbg.h> 204 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 205 206 Link k[5]; 207 208 int Array[5][5] = { {21, 12, 11, 10, 1}, 209 {22, 17, 16, 7, 2}, 210 {23, 18, 13, 8, 3}, 211 {24, 19, 14, 9, 4}, 212 {25, 20, 15, 6, 5}}; 213 214 for (int i=0; i<5; ++i) 215 { 216 k[i].ArrayInsert(Array[i],sizeof(Array[i])/sizeof(Array[i][0])); 217 } 218 //for (int i=0; i<5; ++i) 219 //{ 220 // k[i].Print(); 221 //} 222 223 Link link; 224 225 SortLink(k, sizeof(k)/sizeof(k[0]), &link); 226 227 link.Print(); 228 229 system("pause"); 230 }
(转载请注明作者和出处^_* Seven++ http://www.cnblogs.com/sevenPP/ )