顺序表(各种操作合集)
顺序表的两种创建方式:
方式1:根据函数的返回值创建
通过返回值
返回所申请的内存空间的首地址
; 示例代码:
list_t * create_seq_list_1 ( ) { list_t * p = ( list_t * ) malloc ( sizeof ( list_t ) ) ; if ( NULL == p) { printf ( "内存分配失败\n" ) ; exit ( - 1 ) ; } memset ( p, 0 , sizeof ( list_t ) ) ; return p; }
注意事项: 1.分配完内存地址空间后,一定要检查内存分配是否成功
; 2.若内存分配失败,需要使用shell命令exit(-1)退出
;
方式2:根据地址传参创建
int create_seq_list_2 ( list_t * * p) { if ( NULL == p) { printf ( "入参为NULL\n" ) ; return - 1 ; } * p = ( list_t * ) malloc ( sizeof ( list_t ) ) ; if ( NULL == * p) { printf ( "内存分配失败\n" ) ; return - 1 ; } memset ( * p, 0 , sizeof ( list_t ) ) ; return 0 ; }
注意事项: 1.所传入的形参必须是二级指针变量
,因为二级指针用来存储一级指针变量的地址
,即所申请的顺序表内存空间的地址
; 2.形参传入到创建顺序表的功能函数后,一定要做入参合理性检查
; 3.同方式1一样,分配完内存地址空间后,一定要检查内存分配是否成功
;
顺序表的两种插入方式:
方式1:尾插法
int insert_seq_list_1 ( list_t * seq_list, int data) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } if ( N == seq_list-> count) { printf ( "顺序表已满,插入失败\n" ) ; return - 1 ; } seq_list-> a[ seq_list-> count] . num = data; seq_list-> count++ ; return 0 ; }
注意事项: 1.形参传入到具有插入数据元素功能的函数后,需要做入参合理性检查
; 2.还需要判断此时顺序表所存储的数据元素是否已满
; 3.本示例代码中的count是计数的变量
,每次插入一个数据元素后,需要加1
,此处易忽略
;
方式2:任意位置插入新数据
在顺序表的任意位置插入
数据元素,代码如下: 示例代码:
int insert_seq_list_2 ( list_t * seq_list, int pos, int data) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } if ( N == seq_list-> count) { printf ( "顺序表已满,插入失败\n" ) ; return - 1 ; } if ( pos < 0 || pos > seq_list-> count) { printf ( "插入位置不合理,插入失败\n" ) ; return - 1 ; } int i = 0 ; i = seq_list-> count- 1 ; while ( i >= pos) { seq_list-> a[ i+ 1 ] = seq_list-> a[ i] ; i-- ; } seq_list-> a[ pos] . num = data; seq_list-> count++ ; return 0 ;
}
注意事项: 1.同方式1:形参传入到具有插入数据元素功能的函数后,需要做入参合理性检查
; 2.也同方式1:还需要判断此时顺序表所存储的数据元素是否已满
; 3.判断所要插入数据元素的位置在顺序表中是否合理
; 4.可以采用while循环或者for循环
的方式找到所要插入数据元素的位置后,此位置的数据元素以及此位置之后的所有数据元素,依次向后挪动一个位置
,目的是腾出所指定的待插入位置
; 5.将所要插入的数据元素的值赋值给该位置的值,也就是覆盖,记得count加1
;
顺序表的两种删除方式:
方式1:尾删法
在顺序表的末端删除所存储的数据元素,代码如下: 示例代码:
int delete_seq_list_1 ( list_t * seq_list) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } if ( 0 == seq_list-> count) { printf ( "顺序表为空,删除失败\n" ) ; return - 1 ; } seq_list-> count-- ; return 0 ;
}
注意事项: 1.形参传入到具有删除数据元素功能的函数后,需要做入参合理性检查
; 2.还需要判断此时顺序表所存储的数据元素是否为空
; 3.count是计数的变量
,每次删除一个数据元素后,需要减1
,此处易忽略
;
方式2:任意位置删除旧数据
在顺序表的任意位置删除数据元素,代码如下: 示例代码:
int delete_seq_list_2 ( list_t * seq_list, int pos) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } if ( 0 == seq_list-> count) { printf ( "顺序表为空,删除失败\n" ) ; return - 1 ; } if ( pos < 0 || pos >= seq_list-> count) { printf ( "删除位置不合理,删除失败\n" ) ; return - 1 ; } int i = pos; while ( i < seq_list-> count- 1 ) { seq_list-> a[ i] = seq_list-> a[ i+ 1 ] ; i++ ; } seq_list-> count-- ; return 0 ; }
注意事项: 1.同方式1:形参传入到具有删除数据元素功能的函数后,需要做入参合理性检查
; 2.也同方式1:还需要判断此时顺序表所存储的数据元素是否为空
; 3.判断所要删除数据元素的位置在顺序表中是否合理
,一定要区别在任意位置插入数据元素的位置合理性检查
,两者略有不同,防止越界操作,所导致运行结果出错
; 4.可以采用while循环或者for循环
的方式找到所要删除数据元素的位置后,此位置之后的所有数据元素,依次向前挪动一个位置
,目的是删除所指定的待删除位置
; 5.删除所指定位置的数据元素后,记得count减1
;
顺序表的两种修改方式:
方式1:根据位置修改
根据顺序表中数据元素的位置
进行修改,代码如下: 示例代码:
int modify_seq_list_1 ( list_t * seq_list, int pos, int data) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } if ( pos < 0 || pos >= seq_list-> count) { printf ( "修改位置不合理,修改失败\n" ) ; return - 1 ; } seq_list-> a[ pos] . num = data; return 0 ;
}
注意事项: 1.形参传入到具有修改数据元素功能的函数后,需要做入参合理性检查
; 2.判断所要修改数据元素的位置在顺序表中是否合理
,if条件语句内容和任意位置删除功能函数一致;
方式2:根据数值修改
根据顺序表中数据元素的值
进行修改,代码如下: 示例代码:
int modify_seq_list_2 ( list_t * seq_list, int data1, int data2) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } int i = 0 ; int count = 0 ; while ( i < seq_list-> count) { if ( seq_list-> a[ i] . num == data1) { seq_list-> a[ i] . num = data2; count++ ; } i++ ; } if ( 0 == count) { printf ( "顺序表中无所要修改的值\n" ) ; } return 0 ;
}
注意事项: 1.同方式1,形参传入到具有修改数据元素功能的函数后,需要做入参合理性检查
; 2.可以采用while循环或者for循环
的方式找到所要修改数据元素的值后,将新值赋值于旧值
即可; 3.该函数中定义的count变量
,用来记录
顺序表中有无所要修改的值
;
顺序表的查找:
根据顺序表中数据元素的位置
进行查找
,代码如下: 示例代码:
int search_seq_list ( list_t * seq_list, int pos, int * num) { if ( NULL == seq_list || NULL == num) { printf ( "内存分配失败\n" ) ; return - 1 ; } if ( pos < 0 || pos >= seq_list-> count) { printf ( "查找位置不合理,查找失败\n" ) ; return - 1 ; } * num = seq_list-> a[ pos] . num; return 0 ;
}
注意事项: 1.形参传入到具有查找数据元素功能的函数后,需要做入参合理性检查
,比如函数中的形参seq_list和num
; 2.判断所要查找数据元素的位置在顺序表中是否合理,if条件语句内容
和任意位置删除功能函数一致;
顺序表的排序:
根据顺序表中每个数据元素的大小
,对数据元素做冒泡排序
,代码如下: 示例代码:
int sort_seq_list ( list_t * seq_list) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } for ( int i = 0 ; i < seq_list-> count - 1 ; i++ ) { for ( int j = 0 ; j < seq_list-> count - 1 - i; j++ ) { if ( seq_list-> a[ j] . num > seq_list-> a[ j+ 1 ] . num) { data_t temp = seq_list-> a[ j] ; seq_list-> a[ j] = seq_list-> a[ j+ 1 ] ; seq_list-> a[ j+ 1 ] = temp; } } } printf ( "本次排序结束\n" ) ; return 0 ;
}
注意事项: 1.定义一个结构体变量,作为第三方变量
,根据if条件语句
,交换两个数据元素的位置
; 2.注意越界问题,比如第二层for循环
中j < seq_list->count - 1 - i;
的-1
是为了防止越界
;
顺序表的去重:
11 33 55 55 66 66 66 66
本次去重结束
11 33 55 66
int del_rep_seq_list ( list_t * seq_list) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } for ( int i = 0 ; i < seq_list-> count; i++ ) { for ( int j = i + 1 ; j < seq_list-> count; ) { if ( seq_list-> a[ i] . num == seq_list-> a[ j] . num) { for ( int k = j; k < seq_list-> count- 1 ; k++ ) { seq_list-> a[ k] = seq_list-> a[ k+ 1 ] ; } seq_list-> count-- ; } else { j++ ; } } } printf ( "本次去重结束\n" ) ; return 0 ;
}
注意事项: 1.第二层for循环
是为了在顺序表中寻找相同的数据元素
; 2.顺序表去重的具体操作
方法和在顺序表的任意位置删除数据元素
的操作一致
;
顺序表的清空:
只需要将结构体变量的成员count赋值0
即可清空顺序表
; 示例代码:
int clean_seq_list ( list_t * seq_list) { if ( NULL == seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } seq_list-> count = 0 ; printf ( "清空顺序表完成\n" ) ; return 0 ;
}
注意事项: 形参传入到具有清空数据元素功能的函数后,需要做入参合理性检查;
顺序表的销毁:
int destroy_seq_list ( list_t * * seq_list) { if ( NULL == seq_list || NULL == * seq_list) { printf ( "入参为NULL\n" ) ; return - 1 ; } free ( * seq_list) ; * seq_list = NULL ; printf ( "销毁顺序表完成\n" ) ; return 0 ; }
注意事项: 1.形参传入到具有销毁数据元素功能的函数后,需要做入参合理性检查; 2.使用free函数释放顺序表的内存空间
后,要记得做*seq_list = NULL;
操作,这样是为了防止内存空间出现野指针
;