H.265編碼視訊播放器EasyPlayerPro-WIN版播放HLS協議視訊流顯示時間與實際不符如何修復?
阿新 • • 發佈:2020-11-04
雙向非迴圈連結串列,被封裝成一個類;使用動態記憶體分配,連結串列會根據實際包含元素的數量申請和釋放記憶體。
本實現只涉及C++中的基本資料型別,不使用c++中任何高階資料結構或類或集合,有助於深入理解連結串列的設計和實現思想。
基礎方法:
- 判空
- 指定位置插入元素
- 指定位置刪除元素
- 指定值刪除元素
擴充套件方法:
- 輸出連結串列中元素個數
- 按順序輸出連結串列元素
sichlinklist.h
1 #pragma once 2 #include<string> 3 4 namespace sichdc { 5 6 class SLinklist {7 // 雙向連結串列 8 9 private: 10 11 std::string name; // 物件名(與連結串列實現無關) 12 13 class Node { 14 // 雙向連結串列的節點 15 // 將節點類定義為內部類,這樣連結串列的使用者使用連結串列時就不要顧慮連結串列的內部實現 16 17 private: 18 19 20 int nameid; // 表示物件的名稱的整數21 22 int value; // 節點的值 23 Node* prev; // 指向前一個節點的指標 24 Node* next; // 指向下一個節點的指標 25 26 public: 27 28 static int count; // 記錄Node物件存在的個數 29 30 Node(); 31 // 無參建構函式 32 Node(int v, Node* p, Node* n);33 // 帶參建構函式 34 ~Node(); 35 // 解構函式,和連結串列實現無關 36 37 void SetValue(int v); 38 // 設定value的值 39 int GetValue(); 40 // 返回value的值 41 void SetPrev(Node* p); 42 // 設定前置節點 43 Node* GetPrev(); 44 // 返回前置節點的地址 45 void SetNext(Node* n); 46 // 設定後置節點 47 Node* GetNext(); 48 // 返回後置節點的地址 49 }; 50 51 Node* head; // 連結串列的頭指標,指向連結串列的第一個元素 52 int size; 53 54 public: 55 56 SLinklist(std::string n); 57 // 建構函式 58 59 ~SLinklist(); 60 /* 61 * 連結串列的實現涉及動態記憶體分配,所以要在解構函式中回收記憶體 62 */ 63 64 bool IsEmpty(); 65 // 判空 66 67 bool Insert(int place, int value); 68 /* 69 * 向連結串列中place位置插入值為value的節點 70 * 原place位置的元素後移 71 */ 72 bool DeleteByPlace(int place); 73 /* 74 * 根據位置刪除連結串列中的元素 75 */ 76 bool DeleteByValue(int value); 77 /* 78 * 根據值刪除連結串列中的元素 79 */ 80 int Search(int value); 81 /* 82 * 查詢連結串列中是否存在相應元素 83 * 返回連結串列中值為value的第一個元素在連結串列中的位置 84 */ 85 86 int Size(); 87 /* 88 * 返回連結串列中元素的數量 89 */ 90 void ShowInfo(); 91 /* 92 * 先從前向後輸出連結串列中的所有元素 93 * 再從後向前輸出連結串列中的所有元素 94 */ 95 }; 96 97 class SLinklistTest { 98 99 public: 100 void Test(); 101 }; 102 }
sichlinklist.cpp
1 #include"sichlinklist.h" 2 3 #include<iostream> 4 5 6 namespace sichdc { 7 8 int SLinklist::Node::count = 0; 9 SLinklist::Node::Node() { 10 11 nameid = count; 12 count++; 13 14 value = 0; 15 prev = nullptr; 16 next = nullptr; 17 18 std::cout << "SLinklist::Node " << nameid << "被建立" << std::endl; 19 } 20 SLinklist::Node::Node(int v, Node* p, Node* n) { 21 22 nameid = count; 23 count++; 24 25 value = v; 26 prev = p; 27 next = n; 28 29 std::cout << "SLinklist::Node " << nameid << " 值:" << value << "被建立" << std::endl; 30 } 31 SLinklist::Node::~Node() { 32 33 count--; 34 std::cout << "SLinklist::Node " << nameid << " 值:" << value << "被銷燬" << std::endl; 35 } 36 void SLinklist::Node::SetValue(int v) { value = v; } 37 int SLinklist::Node::GetValue() { return value; } 38 void SLinklist::Node::SetPrev(SLinklist::Node* p) { prev = p; } 39 SLinklist::Node* SLinklist::Node::GetPrev() { return prev; } 40 void SLinklist::Node::SetNext(SLinklist::Node* n) { next = n; } 41 SLinklist::Node* SLinklist::Node::GetNext() { return next; } 42 43 SLinklist::SLinklist(std::string n) { 44 45 name = n; 46 head = nullptr; 47 size = 0; 48 } 49 SLinklist::~SLinklist() { 50 51 Node* temp = nullptr; 52 for (int i = 0; i < size; ++i) { 53 54 // std::cout << "定位:~Slinklist()" << std::endl; 55 56 temp = head; 57 head = head->GetNext(); 58 delete temp; 59 } 60 } 61 bool SLinklist::IsEmpty() { return size == 0 && head == nullptr; } 62 bool SLinklist::Insert(int place, int value) { 63 64 Node* n = new Node(); // n指向的節點儲存在動態記憶體區,不會在函式退出時被銷燬 65 n->SetValue(value); 66 67 if (IsEmpty()) { 68 // 特殊情況,插入空連結串列 69 70 if (place == 0) { 71 72 n->SetPrev(nullptr); 73 n->SetNext(nullptr); 74 75 head = n; 76 77 size++; 78 return true; 79 } 80 else { 81 82 delete n; 83 return false; 84 } 85 } 86 if (place == 0) { 87 // 特殊情況,插入到連結串列頭 88 89 n->SetPrev(nullptr); 90 n->SetNext(head); 91 92 head->SetPrev(n); 93 94 head = n; 95 96 size++; 97 return true; 98 } 99 if (place < 0 || place >= size) { 100 // 插入位置不存在 101 102 delete n; 103 return false; 104 } 105 if (place > 0 && place < size) { 106 // 一般情況 107 108 Node* temp{}; 109 temp = head->GetNext(); 110 for (int i = 1; i < size; ++i) { 111 112 if (i == place) { 113 114 n->SetPrev(temp->GetPrev()); 115 n->SetNext(temp); 116 117 temp->GetPrev()->SetNext(n); 118 119 temp->SetPrev(n); 120 121 size++; 122 return true; 123 } 124 125 temp = temp->GetNext(); 126 } 127 } 128 129 return false; 130 } 131 bool SLinklist::DeleteByPlace(int place) { 132 133 if (place < 0 || place >= size) { return false; } // 不能刪除不存在的位置 134 135 Node* temp{}; // 遍歷連結串列的指標 136 temp = head; 137 for (int i = 0; i < size; ++i) { 138 139 if (i == place) { 140 141 if (i == 0 && i == size - 1) { 142 // 連結串列中只有一個元素 143 144 head = nullptr; 145 delete temp; 146 147 size--; 148 return true; 149 } 150 if (i == 0) { 151 // 刪除連結串列首元素 152 153 head = temp->GetNext(); 154 temp->GetNext()->SetPrev(nullptr); 155 156 delete temp; 157 158 size--; 159 return true; 160 } 161 if (i == size - 1) { 162 // 刪除連結串列尾元素 163 164 temp->GetPrev()->SetNext(nullptr); 165 166 delete temp; 167 168 size--; 169 return true; 170 } 171 if (i > 0 && i < size - 1) { 172 // 刪除連結串列一般元素 173 174 temp->GetPrev()->SetNext(temp->GetNext()); 175 temp->GetNext()->SetPrev(temp->GetPrev()); 176 177 delete temp; 178 179 size--; 180 return true; 181 } 182 } 183 184 temp = temp->GetNext(); 185 } 186 187 return false; 188 } 189 bool SLinklist::DeleteByValue(int value) { 190 191 Node* temp{}; // 遍歷連結串列的指標 192 temp = head; 193 for (int i = 0; i < size; ++i) { 194 195 if (temp->GetValue() == value) { 196 197 if (i == 0 && i == size - 1) { 198 199 head = nullptr; 200 201 delete temp; 202 size--; 203 return true; 204 } 205 if (i == 0) { 206 // 刪除連結串列首元素 207 208 head = temp->GetNext(); 209 temp->GetNext()->SetPrev(nullptr); 210 211 delete temp; 212 213 size--; 214 return true; 215 } 216 if (i == size - 1) { 217 // 刪除連結串列尾元素 218 219 temp->GetPrev()->SetNext(nullptr); 220 221 delete temp; 222 223 size--; 224 return true; 225 } 226 if (i > 0 && i < size - 1) { 227 // 刪除連結串列一般元素 228 229 temp->GetPrev()->SetNext(temp->GetNext()); 230 temp->GetNext()->SetPrev(temp->GetPrev()); 231 232 delete temp; 233 234 size--; 235 return true; 236 } 237 } 238 239 temp = temp->GetNext(); 240 } 241 242 return false; 243 } 244 int SLinklist::Search(int value) { 245 246 Node* temp{}; // 遍歷連結串列的指標 247 temp = head; 248 for (int i = 0; i < size; ++i) { 249 250 if (temp->GetValue() == value) { return i; } 251 252 temp = temp->GetNext(); 253 } 254 255 return -1; 256 // 連結串列中不存在指定元素 257 } 258 int SLinklist::Size() { return size; } 259 void SLinklist::ShowInfo() { 260 261 using namespace std; 262 263 if (IsEmpty()) { 264 265 cout << "連結串列為空\n" << endl; 266 return; 267 } 268 269 Node* temp{}; // 遍歷連結串列的指標 270 temp = head; 271 cout << "正序:"; 272 cout << temp->GetValue() << ", "; 273 while (temp->GetNext() != nullptr) { 274 275 temp = temp->GetNext(); 276 cout << temp->GetValue() << ", "; 277 } 278 cout << endl; 279 280 cout << "逆序:"; 281 cout << temp->GetValue() << ", "; 282 while (temp->GetPrev() != nullptr) { 283 284 temp = temp->GetPrev(); 285 cout << temp->GetValue() << ", "; 286 } 287 cout << "\n" << endl; 288 } 289 290 void SLinklistTest::Test() { 291 292 using namespace std; 293 294 SLinklist sll{ "sll" }; 295 296 string cmd{}; // 用於接受使用者命令 297 cout << "_> "; 298 cin >> cmd; 299 while (cmd != "退出") { 300 301 if (cmd == "空連結串列") { 302 303 cout << (sll.IsEmpty() ? "空連結串列" : "非空連結串列") << "\n" << endl; 304 } 305 else if (cmd == "連結串列大小") { 306 307 cout << sll.Size() << "\n" << endl; 308 } 309 else if (cmd == "插入") { 310 311 int p{}; 312 int v{}; 313 cout << "輸入位置:"; 314 cin >> p; 315 cout << "輸入資料:"; 316 cin >> v; 317 cout << sll.Insert(p, v) << "\n" << endl; 318 } 319 else if (cmd == "按位置刪除") { 320 321 int p{}; 322 cout << "輸入位置:"; 323 cin >> p; 324 cout << sll.DeleteByPlace(p) << "\n" << endl; 325 } 326 else if (cmd == "按值刪除") { 327 328 int v{}; 329 cout << "輸入值:"; 330 cin >> v; 331 cout << sll.DeleteByValue(v) << "\n" << endl; 332 } 333 else if (cmd == "查詢") { 334 335 int v{}; 336 cout << "輸入值:"; 337 cin >> v; 338 cout << sll.Search(v) << "\n" << endl; 339 } 340 else if (cmd == "檢查") { 341 342 sll.ShowInfo(); 343 } 344 else { 345 346 cout << "不支援當前命令!" << "\n" << endl; 347 } 348 349 cout << "_> "; 350 cin >> cmd; 351 } 352 } 353 }
源.cpp
1 #include"sichlinklist.h" 2 #include<iostream> 3 4 int main() { 5 6 using namespace std; 7 using sichdc::SLinklistTest; 8 9 cout << "## 程式開始 ##\n"; 10 11 SLinklistTest sllt{}; 12 sllt.Test(); 13 14 cout << "## 程式結束 ##\n"; 15 return 0; 16 }
備註:
sichlinklist.h標頭檔案中定義了3個類:SLinklist,Node和SLinklistTest。
SLinklist是連結串列類;Node是定義在SLinklist中的內部類,表示連結串列中的節點;SLinklistTest是測試連結串列用的類。
sichlinklist.cpp是這三個類的實現。
源.cpp中定義程式入口函式main()。