【1】線性結構
在數據元素的非空有限集中,線性結構特點:
a. 存在唯一的一個被稱作“第一個”的數據元素
b. 存在唯一的一個被稱作“最后一個”的數據元素
c. 除第一個之外,集合中的每個數據元素均只有一個前驅
d. 除最后一個之外,集合中每個數據元素均只有一個后繼
【2】線性表
線性表是最常用且簡單的一種數據結構。
一個線性表是n個數據元素的有限序列。
線性表中的數據元素可以是各種各樣的,但同一線性表中的元素必定具有相同特性。
在復雜的線性表中,一個數據元素可以由若干個數據項組成。這種情況下,常把數據元素稱為記錄。
而含大量記錄的線性表稱為文件。
【3】順序表
線性表的順序表示指用一組地址連續的存儲單元依次存儲線性表的數據元素。
線性表的順序存儲結構如下:
【4】順序表的優缺點
優點:樂於隨機存取。
因為物理結構和邏輯結構均連續,所以數據存取尤其簡易。
缺點:悲在插入刪除
為了保證存儲的連續性,插入或刪除會比較麻煩。
另外一點:順序存儲要求明確數據的規模用來分配給數據空間。
【5】C++實現順序表代碼
<1>SeqList.h文件

1 #include <iostream> 2 #include <assert.h> 3 #include <typeinfo.h> 4 #include <string.h> 5 using namespace std; 6 7 #define UM_QUIT 0 8 #define UM_INPUTR 1 9 #define UM_PRINT 2 10 #define UM_INPUTH 3 11 #define FINDVALUE 4 12 #define UM_INSERT 5 13 #define UM_REMOVE 6 14 #define UM_SORT 7 15 #define UM_REMOVEALL 8 16 #define UM_REVERSE 9 17 #define UM_ERASE 10 18 #define UM_PVPOS 11 19 20 #define MAXSIZE 10 21 #define INCSIZE 5 22 23 template <class Type> 24 class SeqList 25 { 26 private: 27 Type* m_pData; //數據區域 28 size_t m_nMaxSize; //最大容量 29 size_t m_nLen; //元素個數 30 31 public: 32 SeqList(size_t size = MAXSIZE); 33 SeqList(const SeqList<Type>& sqList); 34 SeqList<Type>& operator=(const SeqList<Type>& sqList); 35 ~SeqList(); 36 37 public: 38 size_t GetMaxSize() const; 39 void SetMaxSize(size_t nMaxSize) const; 40 size_t GetLength() const; 41 void SetLength(size_t nLen) const; 42 43 public: 44 bool IsFull() const; 45 bool IsEmpty() const; 46 bool IsElement(const Type& Value); 47 void Push_Back(const Type& Value); 48 void Push_Front(const Type& Value); 49 void At(const size_t pos); 50 size_t FindPos(const Type& Value); 51 void Insert(const size_t pos, const Type& Value); 52 void Remove(const Type& Value); 53 void Erase(const size_t pos); 54 void RemoveAll(const Type& Value); 55 void Sort(); 56 void Reverse(); 57 void Print() const; 58 59 private: 60 bool IncSize(); 61 void Swap(const size_t leftpos, const size_t rightpos); 62 }; 63 //基本屬性函數 64 template <class Type> 65 size_t SeqList<Type>::GetMaxSize() const 66 { 67 return m_nMaxSize; 68 } 69 template <class Type> 70 void SeqList<Type>::SetMaxSize(size_t nMaxSize) const 71 { 72 m_nMaxSize = nMaxSize; 73 } 74 template <class Type> 75 size_t SeqList<Type>::GetLength() const 76 { 77 return m_nLen; 78 } 79 template <class Type> 80 void SeqList<Type>::SetLength(size_t nLen) const 81 { 82 m_nLen = nLen; 83 } 84 // 作用:擴充順序表容量 85 // 當數據數量大於最大容量時,為順序表增加容量 86 // 增加度量為INCSIZE 87 template <class Type> 88 bool SeqList<Type>::IncSize() 89 { 90 Type* pNewDate = new Type[m_nMaxSize + INCSIZE + 1]; 91 if (NULL == pNewDate) 92 return false; 93 memcpy(pNewDate, m_pData, sizeof(Type) * (m_nLen + 1)); 94 m_pData = pNewDate; 95 m_nMaxSize += INCSIZE; 96 return true; 97 } 98 //交換數據 99 template <class Type> 100 void SeqList<Type>::Swap(const size_t leftpos, const size_t rightpos) 101 { 102 Type temp = m_pData[leftpos]; 103 m_pData[leftpos] = m_pData[rightpos]; 104 m_pData[rightpos] = temp; 105 } 106 //默認復合構造函數 107 template <class Type> 108 SeqList<Type>::SeqList(size_t size = MAXSIZE) 109 { 110 m_nMaxSize = size > MAXSIZE ? size : MAXSIZE; 111 m_pData = new Type[m_nMaxSize + 1]; 112 assert(m_pData != NULL); 113 m_nLen = 0; 114 } 115 //拷貝構造函數 116 template <class Type> 117 SeqList<Type>::SeqList(const SeqList<Type>& sqList) 118 { 119 if (this != &sqList) 120 { 121 m_pData = new Type[sqList.m_nMaxSize + 1]; 122 if (m_pData != NULL) 123 { 124 memcpy(m_pData, sqList.m_pData, sizeof(Type) * (sqList.m_nLen + 1)); 125 } 126 m_nMaxSize = sqList.m_nMaxSize; 127 m_nLen = sqList.m_nLen; 128 } 129 } 130 //賦值函數(思考什么時候調用賦值函數) 131 template <class Type> 132 SeqList<Type>& SeqList<Type>::operator=(const SeqList<Type>& sqList) 133 { 134 m_nLen = sqList.m_nLen; 135 m_nMaxSize = sqList.m_nMaxSize; 136 memcpy(m_pData, sqList.m_pData, sizeof(Type) * (sqList.m_nLen + 1)); 137 return *this; 138 } 139 //析構函數 140 template <class Type> 141 SeqList<Type>::~SeqList() 142 { 143 if (m_pData != NULL) 144 { 145 delete []m_pData; 146 m_pData = NULL; 147 } 148 m_nMaxSize = 0; 149 m_nLen = 0; 150 } 151 //判滿 152 template <class Type> 153 bool SeqList<Type>::IsFull() const 154 { 155 return m_nLen == m_nMaxSize; 156 } 157 //判空 158 template <class Type> 159 bool SeqList<Type>::IsEmpty() const 160 { 161 return 0 == m_nLen; 162 } 163 //是否是順序表中元素 164 template <class Type> 165 bool SeqList<Type>::IsElement(const Type& Value) 166 { 167 size_t pos = FindPos(Value); 168 return 0 != pos; 169 } 170 //從順序表末尾添加元素 171 template <class Type> 172 void SeqList<Type>::Push_Back(const Type& Value) 173 { 174 if (IsFull() && !IncSize()) //注意寫法用意 175 return; 176 m_pData[++m_nLen] = Value; 177 } 178 //從順序表首部添加元素 179 template <class Type> 180 void SeqList<Type>::Push_Front(const Type& Value) 181 { 182 if (IsFull() && !IncSize()) 183 return; 184 for (size_t i = m_nLen; i > 0; --i) 185 { 186 m_pData[i + 1] = m_pData[i]; 187 } 188 ++m_nLen; 189 m_pData[1] = Value; 190 } 191 //輸出對應索引處的數據 192 template <class Type> 193 void SeqList<Type>::At(const size_t pos) 194 { 195 if (pos <= 0 || pos > m_nLen) 196 cout << "輸入下標有誤!" << endl; 197 else 198 cout << pos << "位置的數據為:" << m_pData[pos] << endl; 199 } 200 //查找某數據的索引 201 template <class Type> 202 size_t SeqList<Type>::FindPos(const Type& Value) 203 { 204 m_pData[0] = Value; 205 size_t i = m_nLen; 206 while (m_pData[i] != Value) 207 { 208 --i; 209 } 210 return i; 211 } 212 //在索引處插入值 213 template <class Type> 214 void SeqList<Type>::Insert(const size_t pos, const Type& Value) 215 { 216 if (pos <= 0 || pos > m_nLen + 1) 217 return; 218 if (IsFull() && !IncSize()) 219 return; 220 221 ++m_nLen; 222 for (size_t i = m_nLen; i > pos; --i) 223 { 224 m_pData[i] = m_pData[i-1]; 225 } 226 m_pData[pos] = Value; 227 } 228 //移除某個值 229 template <class Type> 230 void SeqList<Type>::Remove(const Type& Value) 231 { 232 if (IsElement(Value)) 233 { 234 size_t pos = FindPos(Value); 235 Erase(pos); 236 } 237 else 238 { 239 cout << "輸入數據不存在!" << endl; 240 } 241 } 242 //按索引刪除數據 243 template <class Type> 244 void SeqList<Type>::Erase(const size_t pos) 245 { 246 if (pos <= 0 || pos > m_nLen) 247 { 248 cout << "輸入錯誤" << endl; 249 } 250 else 251 { 252 for (size_t i = pos; i < m_nLen; ++i) 253 { 254 m_pData[i] = m_pData[i+1]; 255 } 256 --m_nLen; 257 cout << "刪除成功!刪除后結果如下:" << endl; 258 Print(); 259 } 260 } 261 //刪除全部(刪除所有出現在順序表中的某值) 262 template <class Type> 263 void SeqList<Type>::RemoveAll(const Type& Value) 264 { 265 if (IsElement(Value)) 266 { 267 for (size_t i = m_nLen; i > 0; --i) 268 { 269 if (m_pData[i] == Value) 270 Remove(Value); 271 } 272 273 cout << "刪除全部成功!刪除后結果如下:" << endl; 274 Print(); 275 } 276 else 277 { 278 cout << "輸入的數據不存在!" << endl; 279 } 280 } 281 //順序表數據排序 282 template <class Type> 283 void SeqList<Type>::Sort() 284 { 285 if (m_nLen > 2) 286 { 287 size_t i = 0, j = 0; 288 for (i = 2; i <= m_nLen; ++i) 289 { 290 if (m_pData[i] < m_pData[i - 1]) 291 { 292 m_pData[0] = m_pData[i]; 293 j = i - 1; 294 do 295 { 296 m_pData[j + 1] = m_pData[j]; 297 --j; 298 } while(m_pData[j] > m_pData[0]); 299 m_pData[j + 1] = m_pData[0]; 300 } 301 } 302 } 303 } 304 //逆置順序表 305 template <class Type> 306 void SeqList<Type>::Reverse() 307 { 308 if (m_nLen > 2) 309 { 310 size_t i = 0, j = 0; 311 for (i = 1, j = m_nLen; i < j; ++i, --j) 312 { 313 Swap(i, j); 314 } 315 cout << "逆置結果如下:" << endl; 316 Print(); 317 } 318 } 319 //打印順序表數據信息 320 template <class Type> 321 void SeqList<Type>::Print() const 322 { 323 cout << "容量:" << m_nMaxSize << endl; 324 cout << "元素的個數:" << m_nLen << endl; 325 cout << "數據如下:" << endl; 326 for (size_t i = 1; i <= m_nLen; ++i) 327 { 328 cout << m_pData[i] << " "; 329 } 330 cout << endl; 331 }
<2>TestSeqList.cpp文件

1 #include "SeqList.h" 2 using namespace std; 3 4 void main() 5 { 6 cout << "\t**********************深拷貝************************\t\t\t\t" << endl; 7 SeqList<int> MylistA; 8 MylistA.Push_Back(12); 9 MylistA.Push_Back(23); 10 MylistA.Push_Back(34); 11 cout << "打印MylistA數據信息:" << endl; 12 MylistA.Print(); 13 SeqList<int> YoulistA(MylistA); 14 cout << "打印YoulistA數據信息:" << endl; 15 YoulistA.Print(); 16 17 cout << "\t**********************賦值功能************************\t\t\t\t" << endl; 18 SeqList<int> MylistB, YoulistB; 19 MylistB.Push_Front(10); 20 MylistB.Push_Front(11); 21 MylistB.Push_Front(12); 22 cout << "打印MylistB數據信息:" << endl; 23 MylistB.Print(); 24 YoulistB = MylistB; 25 cout << "打印YoulistB數據信息:" << endl; 26 YoulistB.Print(); 27 28 cout << "測試順序表實現:" << endl; 29 SeqList<int> mylist; 30 int select = 1; 31 int item = 0; 32 size_t pos = 0; 33 while (select != 0) 34 { 35 cout << "\t********************菜單*************************\t\t\t\t" << endl; 36 cout << "\t\t* 1.輸入數據r 2.打印數據 *\t\t\t\t" << endl; 37 cout << "\t\t* 3.輸入數據h 4.按值查詢 *\t\t\t\t" << endl; 38 cout << "\t\t* 5.插入數據 6.刪除數據 *\t\t\t\t" << endl; 39 cout << "\t\t* 7.排序 8.全部刪除 *\t\t\t\t" << endl; 40 cout << "\t\t* 9.逆置 10.位置刪除 *\t\t\t\t" << endl; 41 cout << "\t\t* 11.查詢位置值 0.退出 *\t\t\t\t" << endl; 42 cout << "\t**********************************************\t\t\t\t" << endl; 43 cout << "請選擇操作:" <<endl; 44 cin >> select; 45 switch (select) 46 { 47 case UM_QUIT: //0 48 break; 49 case UM_INPUTR: //1 50 cout << "請輸入數據並以-1結束" << endl; 51 while (cin >> item, item != -1) 52 { 53 mylist.Push_Back(item); 54 } 55 break; 56 case UM_PRINT: //2 57 mylist.Print(); 58 break; 59 case UM_INPUTH: //3 60 cout << "請輸入數據並以-1結束" << endl; 61 while (cin>>item, item != -1) 62 { 63 mylist.Push_Front(item); 64 } 65 break; 66 case FINDVALUE: //4 67 cout << "請輸入查詢的數據 " << endl; 68 cin >> item; 69 pos = mylist.FindPos(item); 70 if (0 == pos) 71 { 72 cout << "查無此數據" << endl; 73 } 74 else 75 { 76 cout << "數據的下標是: " << pos << endl; 77 } 78 break; 79 case UM_INSERT: //5 80 cout << "請輸入插入的數據和位置信息" << endl; 81 cin >> item >>pos; 82 mylist.Insert(pos, item); 83 mylist.Print(); 84 break; 85 case UM_REMOVE: //6 86 cout << "請輸入刪除的數據" << endl; 87 cin >> item; 88 mylist.Remove(item); 89 break; 90 case UM_SORT: //7 91 mylist.Sort(); 92 break; 93 case UM_REMOVEALL: //8 94 cout << "請輸入數據:" << endl; 95 cin >> item; 96 mylist.RemoveAll(item); 97 break; 98 case UM_REVERSE: //9 99 mylist.Reverse(); 100 break; 101 case UM_ERASE: //10 102 cout << "請輸入位置信息:" << endl; 103 cin >> pos; 104 mylist.Erase(pos); 105 break; 106 case UM_PVPOS: //11 107 cout << "請輸入位置信息:" << endl; 108 cin >> pos; 109 mylist.At(pos); 110 break; 111 default: 112 cout << "選擇錯誤,請重新選擇" << endl; 113 } 114 } 115 }
備注:以上實現代碼當時運行環境為VS2010
為什么模板類的.h文件與模板類的.cpp文件沒有像普通類那般分離開,請參見隨筆《模板類 聲明與定義》。
Good Good Study, Day Day Up.
順序 選擇 循環 總結