此讲为线性表的顺序结构实现方式
目录
顺序表的描述用结构体来描述顺序表,结构体中包括表的大小、存放数据的数组、表的最大容量三个数据属性。 方法1:(下面都是基于此实现)
注意这两种定义方式,第一种初始化时需要动态申请空间,第二种不需要动态申请空间,因为数组名称是该数组的首地址常量。 |
void initList(LIST *head); //初始化顺序表 void destroyList(LIST *head); //销毁线性表 boolean insertListElementAt(LIST *head, int index, DATA_TYPE value); //在线性表下标为index的元素之前插入value boolean insertListElementAt2(LIST *head, int k, DATA_TYPE value); //在线性表第k个元素之前插入value boolean appendListElementAtTheLastOne(LIST *head, DATA_TYPE value); //在最后一个有效元素的后面追加一个元素 void showList(LIST list); //显示线性表 void showOneElement(LIST list, int index); //显示线性表中的一个元素 boolean deleteListElementAt(LIST *head, int index); //删除线性表中下标为index的元素 boolean deleteListElementAt2(LIST *head, int k); //删除线性表中第k个元素 int countOfList(LIST list); //查找线性表的元素个数 boolean isListEmpty(LIST list); //判断线性表是否为空 boolean isListFull(LIST list); //判断线性表是否为满 DATA_TYPE getListDataAt(LIST list, int index); //在线性表中查找下标为index的元素 DATA_TYPE getListDataAt(LIST list, int k); //在线性表中查找第k个元素 int getListDataBe(LIST list, int value); //在线性表中查找值为value的元素的下标 void clearList(LIST *head); //清空线性表 |
1.初始化线性表(1)直接定义一个线性表(后面其他功能的实现都是基于此方法)
(2)定义一个指向线性表的指针
|
2.插入操作
注意此处不可写为下面的语句: for(i = head->count-1; i > index; i--){ 原因:若count为1,则index只能为0,此时根本无法进入循环
//++i 置前自增:先对变量(i)值增1,然后用增1后的值,参加所有后续运算; //i++ 滞后自增:先用变量(i)原值参加所有的后续运算,然后再对变量值增1。 这两种插入方法的差别在于下标为index的元素是index+1个元素
|
3.删除操作
|
4.判定线性表为空或满
|
5.查找元素
|
6.输出元素
|
7.清空线性表
|
#include<stdio.h>
#include<malloc.h>
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
#define ERROR_DATA -1
typedef int DATA_TYPE; //后续需要改动,此处只是为了测试程序
#define INIT_MAXSIZE 100
typedef struct SQ_LIST{
DATA_TYPE *data;
int maxSize;
int count;
}LIST;
void initList(LIST *head); //初始化顺序表
void destroyList(LIST *head); //销毁线性表
boolean insertListElementAt(LIST *head, int index, DATA_TYPE value); //在线性表下标为index的元素之前插入value
boolean insertListElementAt2(LIST *head, int k, DATA_TYPE value); //在线性表第k个元素之前插入value
boolean appendListElementAtTheLastOne(LIST *head, DATA_TYPE value); //在最后一个有效元素的后面追加一个元素
void showList(LIST list); //显示线性表
void showOneElement(LIST list, int index); //显示线性表中的一个元素
boolean deleteListElementAt(LIST *head, int index); //删除线性表中下标为index的元素
boolean deleteListElementAt2(LIST *head, int k); //删除线性表中第k个元素
int countOfList(LIST list); //查找线性表的元素个数
boolean isListEmpty(LIST list); //判断线性表是否为空
boolean isListFull(LIST list); //判断线性表是否为满
DATA_TYPE getListDataAt(LIST list, int index); //在线性表中查找下标为index的元素
DATA_TYPE getListDataAt(LIST list, int k); //在线性表中查找第k个元素
int getListDataBe(LIST list, int value); //在线性表中查找值为value的元素的下标
void clearList(LIST *head); //清空线性表
//清空线性表
void clearList(LIST *head){
head->count = 0;
}
//在线性表中查找值为value的元素的下标
int getListDataBe(LIST list, int value){
int i;
for(i = 0; i < list.count; i++){
if(list.data[i] == value){
return i;
}
}
return ERROR_DATA;
}
//在线性表中查找第k个元素
DATA_TYPE getListDataAt2(LIST list, int k){
if(k < 0 || k > list.count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
showOneElement(list,k-1);
return list.data[k-1];
}
//在线性表中查找下标为index的元素
DATA_TYPE getListDataAt(LIST list, int index){
if(index < 0 || index > list.count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
showOneElement(list,index);
return list.data[index];
}
//判断线性表是否为满
boolean isListFull(LIST list){
return list.count == list.maxSize;
}
//判断线性表是否为空
boolean isListEmpty(LIST list){
return list.count == 0;
}
/*
boolean isListEmpty(LIST list){
if(list.count == 0){
return TRUE;
}else{
return FALSE;
}
return list.count == 0;
}
*/
int countOfList(LIST list){
printf("当前线性表的有效元素个数为:");
return list.count;
}
//删除线性表中第k个元素
boolean deleteListElementAt2(LIST *head, int k){
int i;
int count;
if(k < 0 || k > head->count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
for(i = k-1; i < head->count - 1; i++){
head->data[i] = head->data[i+1];
}
head->count--;
printf("删除成功!\n");
count = countOfList(*head);
printf("%d 分别为:", count);
showList(*head);
return TRUE;
}
//删除线性表中下标为index的元素
boolean deleteListElementAt(LIST *head, int index){
int i;
int count;
if(index < 0 || index > head->count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
for(i = index; i < head->count - 1; i++){
head->data[i] = head->data[i+1];
}
head->count--;
printf("删除成功!\n");
count = countOfList(*head);
printf("%d 分别为:", count);
showList(*head);
return TRUE;
}
//显示线性表中的一个元素
void showOneElement(LIST list, int index){
printf("%d ", list.data[index]);
printf("\n");
}
//显示线性表
void showList(LIST list){
int i;
for(i = 0; i < list.count; i++){
printf("%d ", list.data[i]);
}
printf("\n");
}
//在最后一个有效元素的后面追加一个元素
boolean appendListElementAtTheLastOne(LIST *head, DATA_TYPE value){
int count;
if(head->count == head->maxSize){
printf("线性表已满,无法进行插入操作\n");
return FALSE;
}
head->data[head->count] = value;
printf("追加成功!\n");
head->count++;
count = countOfList(*head);
printf("%d 分别为:", count);
showList(*head);
return TRUE;
}
//在线性表第k个元素之前插入value
boolean insertListElementAt2(LIST *head, int k, DATA_TYPE value){
int i;
int count;
if(head->count == head->maxSize){
printf("线性表已满,无法进行插入操作\n");
return FALSE;
}
//遗漏:未对下标进行判断
if(k < 0 || k > head->count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
// for(i = head->count-1; i > k; i--){
// head->data[i+1] = head->data[i];
// }
for(i = head->count; i > k-1; i--){
head->data[i] = head->data[i-1];
}
head->data[k - 1] = value;
//(head->count)++;
++head->count; //课本及老师都用的这个,这是为什么呢???????
//++i 置前自增:先对变量(i)值增1,然后用增1后的值,参加所有后续运算;
//i++ 滞后自增:先用变量(i)原值参加所有的后续运算,然后再对变量值增1。
printf("插入成功!\n");
count = countOfList(*head);
printf("%d 分别为:", count);
showList(*head);
return TRUE;
}
//在线性表下标为index的元素之前插入value
boolean insertListElementAt(LIST *head, int index, DATA_TYPE value){
int i;
int count;
if(head->count == head->maxSize){
printf("线性表已满,无法进行插入操作\n");
return FALSE;
}
//遗漏:未对下标进行判断
if(index < 0 || index > head->count){
printf("您输入的下标有误,请重新输入\n");
return FALSE;
}
// for(i = head->count-1; i > index; i--){
// head->data[i+1] = head->data[i];
// }
for(i = head->count; i > index; i--){
head->data[i] = head->data[i-1];
}
head->data[index] = value;
(head->count)++;
//++head->count; //课本及老师都用的这个,这是为什么呢???????
//++i 置前自增:先对变量(i)值增1,然后用增1后的值,参加所有后续运算;
//i++ 滞后自增:先用变量(i)原值参加所有的后续运算,然后再对变量值增1。
printf("插入成功!\n");
count = countOfList(*head);
printf("%d 分别为:", count);
showList(*head);
return TRUE;
}
//销毁线性表
void destroyList(LIST *head){
free(head->data);
}
//初始化顺序表
void initList(LIST *head){
head->data = (DATA_TYPE *)malloc(sizeof(DATA_TYPE) * INIT_MAXSIZE);
head->maxSize = INIT_MAXSIZE;
head->count = 0;
showList(*head);
}
void main(void){
LIST list;
boolean insertOk1;
boolean insertOk2;
boolean insertOk3;
boolean insertOk4;
boolean insertOk5;
boolean appendOk;
boolean deleteOk1;
boolean deleteOk2;
boolean empty;
DATA_TYPE m1;
DATA_TYPE m2;
int index;
initList(&list);
insertOk1 = insertListElementAt(&list, 0, 10);
insertOk2 = insertListElementAt(&list, 0, 20);
insertOk3 = insertListElementAt(&list, 0, 30);
insertOk4 = insertListElementAt2(&list, 2, 40);
insertOk5 = insertListElementAt2(&list, 4, 50);
appendOk = appendListElementAtTheLastOne(&list, 60);
deleteOk1 = deleteListElementAt(&list, 1);
deleteOk2 = deleteListElementAt2(&list, 3);
empty = isListEmpty(list);
printf("%d \n", empty);
m1 = getListDataAt(list, 0);
m2 = getListDataAt2(list, 1);
index = getListDataBe(list, 10);
printf("%d \n", index);
clearList(&list);
showList(list);
destroyList(&list);
}