[数据结构与算法] (顺序)线性表简单demo程序2
main.c
1 /******************************************************* 2 * @: Project: (顺序)线性表数据结构演示 3 * @: File: list.h 4 * @: Function: 提供(顺序)线性表操作的数据结构定义及方法声明 5 * @: History: 2013-09-23 21:41:19 6 * @: Author: Alimy 7 *******************************************************/ 8 9 /******************************************************* 10 * @:头文件包含 11 *******************************************************/ 12 #ifndef __SQ_LIST_H__ 13 #define __SQ_LIST_H__ 14 15 /******************************************* 16 * @: 数据结构定义 17 ********************************************/ 18 #define SQLIST_INIT_SIZE 100 // 线性表存储空间初始化分配单元数 19 #define SQLIST_INCREMENT_SIZE 10 // 线性表存储空间的分配增量 20 #define ElemType signed short int // 此例子中的数据为有符号短整形,在VC6 中占据16bits 21 22 #define StatusType int //操作状态为int类型 23 #define OK (StatusType)1 24 #define ERROR (StatusType)0 25 26 typedef struct{ 27 ElemType * p_elemBaseAddr; //指向存储基地址 28 int m_currentlength; //当前线性表的数据占用长度 29 int m_listTotalSize; //当前分配的存储空间总长度 30 }SqList, *pSqList; 31 32 33 /******************************************* 34 * @: 外部调用函数声明 35 ********************************************/ 36 extern StatusType InitList_Sq(SqList* pL); //在堆中申请一个空的线性表 37 extern StatusType ListInsert_Sq(SqList* pL,int idx_location, ElemType e);// 在顺序表中插入元素 38 extern StatusType ListDelete_Sq(SqList* pL,int idx_location, ElemType* pe);//在顺序表中删除元素 39 extern int ListLocateElem_Sq(SqList* pL, ElemType e); // 定位顺序表的数据 40 extern StatusType ListDestory_Sq(SqList* pL);//销毁已经存在的顺序表 41 extern StatusType ListClear_Sq(SqList* pL); //将表置为空表 42 extern StatusType ListIsEmpty_Sq(SqList* pL);//判断顺序表是否为空表 43 extern StatusType ListGetElem_Sq(SqList* pL,int idx_location,ElemType* pe); //获取线性表中的元素 44 extern int ListGetLenth_Sq(SqList* pL);//获取表长 45 46 extern StatusType ListPriorElem_Sq(SqList* pL,ElemType cur_e,ElemType *pre_e); //获取某元素的前驱元素 47 extern StatusType ListNextElem_Sq(SqList* pL,ElemType cur_e,ElemType *next_e); // 获取某元素的后继元素 48 extern void ListUnion_Sq(SqList* pLa, SqList* pLb); //两个元素取并集 49 extern void DisplayList_Sq(SqList * pL); // 打印当前的顺序表所有元素 50 51 52 #endif // end of __SQ_LIST_H__
1 /******************************************************* 2 * @: Project: (顺序)线性表数据结构演示 3 * @: File: sq_list.c 4 * @: Function: 提供(顺序)线性表操作的基本函数和方法 5 * @: History: 2013-09-23 21:44:02 6 * @: Author: Alimy 7 *******************************************************/ 8 9 /******************************************************* 10 * @: 头文件包含 11 *******************************************************/ 12 #include "sq_list.h" 13 #include <stdio.h> 14 #include <conio.h> 15 16 17 /******************************************************* 18 * @: (外部&内部)变量声明及定义 19 *******************************************************/ 20 21 /******************************************************* 22 * @: (外部&内部)函数声明及定义 23 *******************************************************/ 24 StatusType InitList_Sq(SqList* pL); //在堆中申请一个空的线性表 25 StatusType ListInsert_Sq(SqList* pL,int idx_location, ElemType e);// 在顺序表中插入元素 26 StatusType ListDelete_Sq(SqList* pL,int idx_location, ElemType* pe);//在顺序表中删除元素 27 int ListLocateElem_Sq(SqList* pL, ElemType e);//在顺序表中定位元素 28 StatusType ListDestory_Sq(SqList* pL);//销毁已经存在的线性表 29 StatusType ListClear_Sq(SqList* pL); //将表置为空表 30 StatusType ListIsEmpty_Sq(SqList * pL);//判断顺序表是否为空表 31 StatusType ListGetElem_Sq(SqList* pL,int idx_location,ElemType* pe); //获取线性表中的元素 32 int ListGetLenth_Sq(SqList* pL);//获取表长 33 void DisplayList_Sq(SqList* pL); 34 35 /******************************************************* 36 * @: 内部函数具体实现 37 *******************************************************/ 38 39 /* 40 * @:动态申请堆中空间作为存储空间 41 * @: 返回值 42 * @: 申请成功 返回OK 43 * @: 申请失败返回ERROR 44 */ 45 StatusType InitList_Sq(SqList* pL){ 46 // int idx = 0; 47 48 if(pL->p_elemBaseAddr != NULL){ //可能造成先前申请的堆空间的丢失 49 printf("顺序表已经被初始化过了,不需要再次初始化\n"); 50 return ERROR; 51 } 52 53 pL->p_elemBaseAddr = (ElemType*)(malloc(SQLIST_INIT_SIZE*sizeof(ElemType))); //尝试在堆中申请空间 54 if(pL->p_elemBaseAddr == NULL){ //初始化空间 申请失败 55 printf("初始化空间失败,无法在堆中申请初始化空间"); 56 return ERROR; 57 } 58 // pL->p_elemBaseAddr = pL->p_elemBaseAddr; //此步骤已经做过 59 pL->m_currentlength = 0; //当前为空表,所以表长为0 60 pL->m_listTotalSize = SQLIST_INIT_SIZE; // 总空间长度为初始化长度 61 printf("顺序表初始化完成,当前表长为 【%d】, 总空间长度为 【%d】 \n",pL->m_currentlength,pL->m_listTotalSize); 62 printf("按任意键进入主菜单 \n"); 63 getch(); 64 // printf("在堆中初始化顺序表成功,堆中的数据是: \n"); 65 // for(idx = 0; idx<pL->m_listTotalSize;idx++){ 66 // printf("pL->p_elemBaseAddr[%d] = %d \n",idx+1,pL->p_elemBaseAddr[idx]); 67 // } 68 return OK; 69 } 70 71 /* 72 * @:在pL 指向的顺序表中的第idx_location位置中插入值为e的元素 73 * @: 返回值 74 * @: 插入成功 返回OK 75 * @: 插入失败 返回ERROR 76 */ 77 78 StatusType ListInsert_Sq(SqList* pL,int idx_location, ElemType e){ 79 ElemType* newBaseAddr = NULL; 80 ElemType* p_WorkHead = NULL; //头 工作指针 81 ElemType* p_WorkTail = NULL; //尾工作指针 82 if((idx_location<1)||(idx_location>pL->m_currentlength+1)){ 83 printf("位置idx_location = 【%d】 值非法,插入元素操作失败 \n",idx_location); 84 return ERROR; // 位置idx_location 值非法 85 } 86 87 if(pL->m_currentlength == pL->m_listTotalSize){ //若表已经满了,就需要继续在堆中申请空间 88 newBaseAddr = (ElemType*)realloc(pL->p_elemBaseAddr,(pL->m_currentlength+SQLIST_INCREMENT_SIZE)*sizeof(ElemType)); 89 if(newBaseAddr == NULL){//申请空间失败 90 printf("当前顺序表已经满了,且尝试在堆中申请新的空间失败,插入操作失败 \n"); 91 return ERROR; 92 }else{ // 申请成功 93 94 pL->p_elemBaseAddr = newBaseAddr; // 修正顺序表参数 95 pL->m_listTotalSize += SQLIST_INCREMENT_SIZE; 96 } 97 } 98 99 100 //空间已经足够 101 p_WorkHead = &pL->p_elemBaseAddr[idx_location-1]; // p_work = pL->elemBaseAddr + idx_location -1; 102 p_WorkTail = &pL->p_elemBaseAddr[pL->m_listTotalSize-1]; // 103 104 for(;p_WorkHead<=p_WorkTail;p_WorkTail--){ // 只要头工作指针不小于尾工作指针,就要做后移操作 105 *(p_WorkTail+1) = *(p_WorkTail); 106 } 107 108 *p_WorkHead = e; // 填入数据 109 pL->m_currentlength += 1; // 修正参数 110 printf("顺序表元素插入操作完成成功,元素被插入的位置为[%d],元素的值为[%d] \n",idx_location,e); 111 return OK; 112 } 113 114 /* 115 * @:删除pL 指向的顺序表中的第idx_location位置的元素,并且将被删除的元素的值赋值给pe指向的内存空间 116 * @: 返回值 117 * @: 删除 成功 返回OK 118 * @: 删除失败 返回ERROR 119 */ 120 121 StatusType ListDelete_Sq(SqList* pL,int idx_location, ElemType* pe){ 122 123 ElemType* p_WorkHead = NULL; //头 工作指针 124 ElemType* p_WorkTail = NULL; //尾工作指针 125 if(pL->m_currentlength == 0){ 126 printf("当前顺序表为空表,无法执行元素删除操作 \n"); 127 return OK; 128 } 129 if((idx_location<1)||(idx_location>pL->m_currentlength)){ // 1 <= idx_location 且idx_location <= pL->m_currentlength 才是合法范围 130 printf("【删除位置 idx_location 有误,请检查数据输入 】\n"); 131 printf("----调试信息输出----\n"); 132 printf("【当前顺序表的表长为 %d 】\n【要删除的元素索引为 %d 】\n ",pL->m_currentlength,idx_location); 133 printf("----调试信息输出----\n"); 134 return ERROR; 135 } 136 137 138 p_WorkHead = &pL->p_elemBaseAddr[idx_location - 1]; 139 p_WorkTail = &pL->p_elemBaseAddr[pL->m_currentlength-1]; 140 141 *pe = *p_WorkHead; // 保存值 142 143 for(;p_WorkHead<p_WorkTail;p_WorkHead++){ 144 *(p_WorkHead) = *(p_WorkHead+1); //向左搬移 145 } 146 147 pL->m_currentlength -= 1; //删除了一个元素 148 printf("删除顺序表元素成功,被删除的元素的值为 %d \n",*pe); 149 return OK; 150 151 152 } 153 154 /* 155 *@: 在pL指向的顺序表中定位值为e的元素. 156 *@:返回值: 157 *@: 若在pL指向的顺序表中不存在值为e的元素,则返回【0】 158 *@: 若在pL指向的顺序表中至少存在一个值为e的元素,则返回值为e的元素的最小索引。 159 */ 160 int ListLocateElem_Sq(SqList* pL, ElemType e){ 161 int idx ; 162 for(idx=1;idx<=pL->m_currentlength;idx++){ 163 if(e == pL->p_elemBaseAddr[idx-1]){ // compare函数即 == 号 ,不同的ElemType类型是compare函数具有多样性,例如ElemType为数组型的时候,compare函数就不能这么写了 164 printf("在顺序表中找到至少一个值为【%d】的元素,元素最小索引为【%d】\n",e,idx); 165 return idx; 166 } 167 } 168 169 //遍历所有顺序表的当前元素,没有找到值为e的元素 170 printf("在当前顺序表中没有找到值为【%d】的元素\n",e); 171 return 0; 172 } 173 174 /* 175 *@: 销毁已经存在的顺序表 176 *@:返回值: 177 *@: 销毁成功返回OK 178 *@: 销毁失败返回ERROR 179 */ 180 181 StatusType ListDestory_Sq(SqList* pL){ 182 if(pL->p_elemBaseAddr == NULL){//本来就是空表 183 printf("当前顺序表本来就是空表,无法进行销毁操作 \n"); 184 return ERROR; 185 } 186 187 free(pL->p_elemBaseAddr); 188 pL->p_elemBaseAddr = NULL; 189 pL->m_currentlength = 0; 190 pL->m_listTotalSize = 0; 191 printf("销毁顺序表成功\n"); 192 return OK; 193 } 194 195 /* 196 *@: 清除顺序表 197 *@:返回值: 198 *@: 清除成功返回OK 199 *@: 清除失败返回ERROR 200 */ 201 StatusType ListClear_Sq(SqList* pL){ //将表置为空表 202 if((pL->m_currentlength==0)&&(pL->m_listTotalSize==0)&&(pL->p_elemBaseAddr==NULL)){ 203 printf("当前顺序表未被初始化,无法执行清除操作\n"); 204 return ERROR; 205 } 206 207 //pL->p_elemBaseAddr = pL->p_elemBaseAddr; //基址不变 208 pL->m_currentlength = 0; //设置为空表 209 //pL->m_listTotalSize = pL->m_listTotalSize;//总空间不变 210 return OK; 211 } 212 213 /* 214 *@: 判断顺序表是否为空表 215 *@:返回值: 216 *@: 顺序表未被初始化或者顺序表不为空表返回ERROR 217 *@: 顺序表存在且表为空表返回OK 218 */ 219 220 StatusType ListIsEmpty_Sq(SqList * pL){//判断顺序表是否为空表 221 if((pL->m_currentlength==0)&&(pL->m_listTotalSize==0)&&(pL->p_elemBaseAddr==NULL)){ 222 printf("当前顺序表未被初始化,请确认顺序表已经被分配空间\n"); 223 return ERROR; 224 } 225 226 if(pL->m_currentlength != 0){ //ListGetCurrentLength_Sq 227 printf("当前顺序表存在,且不为空表"); 228 return ERROR; 229 } 230 else{ 231 printf("当前顺序表存在,且为空表"); 232 return OK; 233 } 234 235 236 } 237 238 /* 239 *@: 获取pL 指向的线性表中的第idx_location 个元素,并将该元素的值赋值给pe指向的内存空间 240 *@:返回值: 241 *@: 获取元素成功返回OK 242 *@: 获取元素失败返回ERROR 243 */ 244 StatusType ListGetElem_Sq(SqList* pL,int idx_location,ElemType* pe){ 245 if(pL->p_elemBaseAddr == NULL){ 246 printf("当前表未被初始化。无法执行获取元素操作 \n"); 247 return ERROR; 248 } 249 250 if((idx_location<1)||(idx_location>pL->m_currentlength)){ //位置索引有误 251 printf("需要获取元素的索引有误,请检查是否符合要求\n"); 252 printf("当前顺序表的 当前长度为 【%d】,要求获取的元素的索引为【%d】\n",pL->m_currentlength,idx_location); 253 return ERROR; 254 } 255 256 *pe = pL->p_elemBaseAddr[idx_location-1];//赋值 257 return OK; 258 259 260 } 261 262 263 /* 264 *@: 获取pL 指向的线性表的当前表长(当pL指向非NULL时) 265 *@:返回值: 266 *@: 当前表长----返回非0 267 *@: pL指向为NULL或者基址指向为NULL(空表或者pL未被初始化) ---返回0 268 */ 269 270 int ListGetLenth_Sq(SqList* pL){ 271 if((pL == NULL)||(pL->p_elemBaseAddr == NULL)){ 272 printf("表为空表或者表未被初始化 ,无法获取表长 \n"); 273 return 0; 274 } 275 return(pL->m_currentlength); 276 } 277 278 279 280 /* 281 * @:打印pL指向的顺序表中的所有元素 282 * @: 返回值(无) 283 */ 284 void DisplayList_Sq(SqList* pL){ 285 int idx = 0; 286 if(pL->m_currentlength == 0){ 287 printf("当前表为空表,打印不出东东 \n"); 288 } 289 else{ 290 printf("当前顺序表共有 %d个元素,依次打印如下 \n",pL->m_currentlength); 291 for(idx = 0; idx < pL->m_currentlength;idx++){ 292 printf("第 %d 个元素的值为 %d \n",idx+1,pL->p_elemBaseAddr[idx]); 293 } 294 295 printf("打印完毕! \n"); 296 } 297 return; 298 } 299 300 301 302 //演示未用到的函数 303 304 StatusType ListPriorElem_Sq(SqList* pL,ElemType cur_e,ElemType *pre_e); //获取某元素的前驱元素 305 StatusType ListNextElem_Sq(SqList* pL,ElemType cur_e,ElemType *next_e); // 获取某元素的后继元素 306 void ListUnion_Sq(SqList* pLa, SqList* pLb); //两个线性表取并集 307 void MergeList_Sq(SqList* pLa, SqList* pLb, SqList *pLc); // 归并非递减排列的顺序表la 和 lb到非递减排列的顺序表 lc中 308 309 310 /* 311 *@:获取pL指向的顺序表中值为cur_e 的元素的前驱元素,并将前驱元素的值赋值给pre_e 指向的内存空间 312 *@:返回值 313 *@: 取前驱元素成功---返回OK 314 *@: 取前驱元素失败---返回ERROR 315 */ 316 317 StatusType ListPriorElem_Sq(SqList* pL,ElemType cur_e,ElemType *pre_e){ 318 int idx_current = 0; 319 idx_current = ListLocateElem_Sq(pL,cur_e); 320 if(0 == idx_current ){ 321 printf("当前线性表中没有值为【%d】的元素,获取前驱元素失败",cur_e); 322 return ERROR; 323 } 324 325 if(1 == idx_current){ 326 printf("值为【%d】的元素是该线性表的第一个元素,根据线性表的定义,第一个元素无前驱元素,获取前驱元素失败",cur_e); 327 return ERROR; 328 } 329 330 *pre_e = pL->p_elemBaseAddr[idx_current-1-1]; //获取前驱元素 331 return OK; 332 333 } 334 335 /* 336 *@:获取pL指向的顺序表中值为cur_e 的元素的后继元素,并将后继元素的值赋值给next_e 指向的内存空间 337 *@:返回值 338 *@: 取后继元素成功---返回OK 339 *@: 取后继元素失败---返回ERROR 340 */ 341 342 StatusType ListNextElem_Sq(SqList* pL,ElemType cur_e,ElemType *next_e){ 343 int idx_current = 0; 344 idx_current = ListLocateElem_Sq(pL,cur_e); 345 346 if(0 == idx_current){ 347 printf("当前线性表中没有值为【%d】的元素,获取后继元素失败",cur_e); 348 return ERROR; 349 } 350 351 if(pL->m_currentlength == idx_current){ 352 printf("值为【%d】的元素是该线性表的最后一个元素,根据线性表的定义,最后一个元素无后继元素,获取后继元素失败",cur_e); 353 return ERROR; 354 } 355 356 *next_e = pL->p_elemBaseAddr[idx_current-1+1]; 357 return OK; 358 } 359 360 361 /* 362 *@: 将所有存在于Lb且不存在于pLa中的元素插入到 La的表尾(先行条件La 和Lb都已经被初始化过了) 363 */ 364 void ListUnion_Sq(SqList* pLa, SqList* pLb){ //两个线性表取并集 365 366 int Lb_Len = ListGetLenth_Sq(pLb); 367 int La_Len = ListGetLenth_Sq(pLb); 368 int idx_location = 0; 369 ElemType e = 0; 370 for(idx_location = 0+1;idx_location < Lb_Len+1;idx_location++){ 371 ListGetElem_Sq(pLb,idx_location,&e); 372 if(0 == ListLocateElem_Sq(pLa,e)){ //La 中无值为e的元素 373 La_Len += 1;//准备插入,增加表的长度 374 ListInsert_Sq(pLa,La_Len,e); 375 } 376 } 377 } 378 379 /* 380 *@:已知线性表La和Lb中的数据元素按值非递减排列 381 *@:归并La和Lb得到新的线性表Lc,Lc中的数据元素也按值非递减排列 382 */ 383 void MergeList_Sq(SqList* pLa, SqList* pLb, SqList *pLc){ 384 int idx1 = 1,idx2 = 1; 385 int La_Len = ListGetLenth_Sq(pLa); 386 int Lb_Len = ListGetLenth_Sq(pLb); 387 int Lc_Len = 0; 388 389 ElemType e1 = 0; 390 ElemType e2 = 0; 391 InitList_Sq(pLc); 392 393 while((idx1<=La_Len)&&(idx2<=Lb_Len)){ // La & Lb 都还有更大元素 394 ListGetElem_Sq(pLa,idx1,&e1); 395 ListGetElem_Sq(pLb,idx2,&e2); //获取更不小元素 396 397 if(e1<=e2){ //小的先插入Lc中去 398 idx1++; // 准备取La中的更不小元素去 399 Lc_Len++; //准备插入Lc 400 ListInsert_Sq(pLc,Lc_Len,e1); 401 } 402 else{ 403 idx2++; // 准备取Lb中的更不小元素去 404 Lc_Len++; //准备插入Lc 405 ListInsert_Sq(pLc,Lc_Len,e2); 406 } 407 408 } 409 410 while(idx1<=La_Len){ //Lb先到头 411 idx1++; 412 Lc_Len++; 413 ListGetElem_Sq(pLa,idx1,&e1); 414 ListInsert_Sq(pLc,Lc_Len,e1); 415 } 416 417 while(idx2<=Lb_Len){ //La先到头 418 idx2++; 419 Lc_Len++; 420 ListGetElem_Sq(pLb,idx2,&e2); 421 ListInsert_Sq(pLc,Lc_Len,e2); 422 } 423 424 }
~不再更新,都不让我写公式,博客园太拉胯了

浙公网安备 33010602011771号