C++數據結構之傳統單鏈表
阿新 • • 發佈:2017-10-03
fad div class for reverse while 結點 next using
這幾天有空重寫一下數據結構,從單鏈表開始吧,這個是C++版本的,後面會根據情況是否補充上C版本的。
這個文章寫了之後,也查看了網絡上其他的數據結構寫法,發現大家的寫法多多少少都有一些不一樣的地方,而
我的寫法也和大家多多少少有一些不一樣的地方,歡迎大家參閱,如果有問題請幫忙指正,我會盡力修改,希望
大家能夠一起進步!謝謝!
LinkList.h頭文件
1 #pragma once 2 #include<iostream> 3 using namespace std; 4 5 class LinkNode 6 { 7 public: 8 int data;9 LinkNode* next; 10 }; 11 12 class LinkList 13 { 14 public: 15 LinkList(); 16 17 //插入操作 18 void InsertLinkNodeByPox(int pox, int val); 19 20 //根據值刪除元素 21 void RemoveLinkNodeByVal(int val); 22 23 //根據位置刪除元素 24 void RemoveLinkNodeByPox(int pox); 25 26 //反轉鏈表 方法1 這個是我第一時候寫的,方法比表原始,本來準備刪除的,不過畢竟是心血,還是放上面把。。。。。。 較笨拙,不推薦。。27 void reverse(); 28 29 //反轉鏈表 方法1 這個簡單 非遞歸方法 30 void reverseSimply(); //方法簡單! 31 32 //遞歸實現鏈表反轉 33 LinkNode* reserveByRecursion(LinkNode* hd); 34 35 //遍歷鏈表 36 void ForEachLinkList(); 37 38 //根據值查找節點的位置 39 LinkNode* FindVal(int val); 40 41 //返回長度 42 int LinkListLength();43 44 45 //清空鏈表 46 void clearList(); 47 48 //析構函數 49 ~LinkList(); 50 51 public: 52 LinkNode* head; 53 54 int length; 55 };
LinkList.cpp實現文件
1 #include "LinkList.h" 2 3 LinkList::LinkList() 4 { 5 this->length = 0; 6 this->head = new LinkNode; 7 head->data = -1; 8 head->next = NULL; 9 } 10 11 void LinkList::InsertLinkNodeByPox(int pox, int val) 12 { 13 if (pox < 0 || pox > this->length) 14 { 15 pox = this->length; 16 } 17 18 LinkNode* pcurNode = this->head; 19 20 //找到插入位置的前一個節點 21 for (int i = 0; i < pox; ++i) 22 { 23 pcurNode = pcurNode->next; 24 } 25 LinkNode* newNode = new LinkNode; 26 newNode->data = val; 27 newNode->next = pcurNode->next; 28 pcurNode->next = newNode; 29 30 this->length++; 31 } 32 33 void LinkList::RemoveLinkNodeByVal(int val) 34 { 35 if (this->length <= 0) 36 { 37 return; 38 } 39 LinkNode* pcurNode = this->head; 40 LinkNode* preNode = this->head; 41 42 for (int i = 0; i < this->length; ++i) 43 { 44 pcurNode = pcurNode->next; 45 if (pcurNode->data == val) 46 { 47 preNode->next = pcurNode->next; 48 delete pcurNode; 49 pcurNode = NULL; 50 this->length--; 51 return; 52 } 53 preNode = pcurNode; 54 } 55 56 } 57 58 void LinkList::RemoveLinkNodeByPox(int pox) 59 { 60 if (pox < 0 || pox >= this->length) 61 { 62 return; 63 } 64 LinkNode* pcurNode = this->head; 65 66 //找到前去節點 67 for (int i = 0; i < pox; ++i) 68 { 69 pcurNode = pcurNode->next; 70 } 71 72 LinkNode* delNode = pcurNode->next; 73 pcurNode->next = delNode->next; 74 delete delNode; 75 delNode = NULL; 76 77 this->length--; 78 } 79 80 void LinkList::reverse() 81 { 82 if (NULL == this->head->next) 83 { 84 return; 85 } 86 LinkNode* pFirst = this->head->next; //指向頭結點 87 88 if (NULL == pFirst->next) 89 { 90 return; 91 } 92 LinkNode* pMid = this->head->next; //指向頭結點的下一個節點 93 94 if (NULL == pMid->next) 95 { 96 pFirst->next = NULL; 97 pMid->next = pFirst; 98 this->head->next = pMid; 99 return; 100 } 101 102 LinkNode* pLast = pMid->next; 103 pFirst->next = NULL; 104 while (true) 105 { 106 pMid->next = pFirst; //讓第二個節點指向第一個節點 107 pFirst = pLast->next; //讓第一個節點挪動到最後一個節點的下一個 108 109 if (NULL == pFirst) 110 { 111 pLast->next = pMid; 112 head->next = pLast; 113 return; 114 } 115 116 pLast->next = pMid; 117 pMid = pFirst->next; 118 119 if (NULL == pMid) 120 { 121 pFirst->next = pLast; 122 head->next = pFirst; 123 return; 124 } 125 126 pFirst->next = pLast; 127 pLast = pMid->next; 128 if (NULL == pLast) 129 { 130 pMid->next = pFirst; 131 head->next = pMid; 132 return; 133 } 134 } 135 } 136 137 void LinkList::reverseSimply() 138 { 139 LinkNode* pnext = this->head->next; //記載下一個節點,也是反轉後的第一個節點 140 141 LinkNode* pcur = NULL; //記載當前的 142 LinkNode* ppre = NULL; //記載前一個節點 143 144 while (true) 145 { 146 if (NULL == pnext->next && NULL == pnext->next) //如果只有頭節點或者只有一個節點,或者pnext到了最後一個節點 147 { 148 this->head->next = pnext; 149 pnext->next = pcur; //防止最後一個節點沒有鏈接上倒數第二個 150 return; 151 } 152 pcur = pnext; 153 pnext = pnext->next; //上一步已經完成占位操作,之後讓自己下移,記載下一個節點指針 154 pcur->next = ppre; //經過上面兩步,當前節點已經下移了一位,讓自己的下一個指向之前的一個節點 155 ppre = pcur; //上一步已經完成反向鏈接過程,讓ppre後移一個節點 156 } 157 158 } 159 160 161 LinkNode * LinkList::reserveByRecursion(LinkNode* hd) 162 { 163 if (NULL == hd->next) //遞歸先找到最後一個節點 164 { 165 this->head->next = hd; 166 return hd; 167 } 168 LinkNode* pcurNode = reserveByRecursion(hd->next); //是反轉前的最後一個節點,反轉後的第一個節點 169 170 pcurNode->next = hd; 171 172 return hd; 173 } 174 175 176 void LinkList::ForEachLinkList() 177 { 178 LinkNode* pcurNode = this->head; 179 180 for (int i = 0; i < this->length; ++i) 181 { 182 pcurNode = pcurNode->next; 183 cout << pcurNode->data << " "; 184 } 185 cout << endl; 186 } 187 188 LinkNode* LinkList::FindVal(int val) 189 { 190 if (this->length <= 0) 191 { 192 return NULL; 193 } 194 195 LinkNode* pcurNode = head; 196 for (int i = 0; i < this->length; ++i) 197 { 198 pcurNode = pcurNode->next; 199 if (pcurNode->data == val) 200 { 201 cout << "找到了!" << endl; 202 return pcurNode; 203 } 204 } 205 return NULL; 206 } 207 208 int LinkList::LinkListLength() 209 { 210 return this->length; 211 } 212 213 214 215 void LinkList::clearList() 216 { 217 if (this->length <= 0) 218 { 219 return; 220 } 221 222 LinkNode* pcurNode = head; 223 LinkNode* pnextNode = head->next; 224 225 for (int i = 0; i < length; ++i) 226 { 227 pcurNode = pnextNode; 228 pnextNode = pcurNode->next; 229 if (pcurNode != NULL) 230 { 231 delete pcurNode; 232 pcurNode = NULL; 233 } 234 } 235 236 this->length = NULL; 237 } 238 239 LinkList::~LinkList() 240 { 241 if (this->length <= 0) 242 { 243 if (NULL != head) 244 { 245 delete head; 246 head = NULL; 247 } 248 return; 249 } 250 251 LinkNode* pcurNode = head; 252 LinkNode* pnextNode = head->next; 253 254 for (int i = 0; i < length; ++i) 255 { 256 pcurNode = pnextNode; 257 pnextNode = pcurNode->next; 258 if (pcurNode != NULL) 259 { 260 delete pcurNode; 261 pcurNode = NULL; 262 } 263 } 264 this->length = 0; 265 if (NULL != head) 266 { 267 delete head; 268 head = NULL; 269 } 270 return; 271 }View Code
C++數據結構之傳統單鏈表