前言
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
提示:以下是本篇文章正文内容,下面案例可供参考
一、顺序表的相关描述
二、顺序表的增删查改;
1.定义顺序表
代码如下(示例):
typedef struct { tempstyle* data; //数据域; int curpity; //链表的容量; int cursize; //链表的长度; }Seqlist;
2.顺序表的初始化
代码如下(示例):
Seqlist* INIT_list(Seqlist* plist)//顺序表初始化; { //对链表的容量进行赋值; plist->curpity = SEQ_INIT_SIZE; plist->cursize = 0; plist->data = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity); //申请动态存储空间; }
3.顺序表查找,删除,插入;
顺序表本质就是一定长度的具有连续地址的数组,所以数据的查询和删除都是在数组的基础上进行,考察的就是数组的应用。
bool insert_list(Seqlist* plist, int pos, tempstyle val) { assert(plist != NULL); if (pos<0 || pos>plist->cursize) { return false; } if (INIT_man(plist) == true) { return false; } else { for (int i = plist->cursize; i > pos; i--) { plist->data[i] = plist->data[i - 1]; } plist->data[pos] = val; plist->cursize += 1; return true; /* for(int i=plist->cursize-1;i>=pos;i--) { plist->data[i+1]=plist->data[i]; } plist->data[pos]=val; plist->cursize+=1; return true; */ } } //查找函数,对输入的值进行查找; int FIND_list(Seqlist* plist, tempstyle val) { assert(plist != NULL); int pos = plist->cursize; while (pos > 0 && plist->data[pos - 1] != val) { pos--; } if (pos == 0) return -1; else return pos; }
4.顺序表的扩容;
顺序表的扩容就是将已有的数据转移到另一个大一点的数组中。可以用realloc函数,也可以用memmove函数,也可以用数组直接单个单个进行转移。以上三种方法我都已经实现。可以自己测试。 bool INIT_seqlist(Seqlist* plist) { assert(plist != NULL); int total; total = plist->curpity * SEQ_SIZE; tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * total); if (plist == NULL) { return false; } else { /* for(int i=0;i<plist->curpity;i++) { newnode[i]=plist->data[i]; } memmove(newnode,plist->data,sizeof(tempstyle)*plist->curpity); free(plist->data); plist->data=newnode; plist->curpity=total; return true;*/ plist->data = (tempstyle*)realloc(plist->data, sizeof(tempstyle) * total);//增加到tatol的空间; plist->cursize += 1; plist->curpity = total; return true; } }
三、顺序表的源代码;
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> //printf #include<stdlib.h> //malloc,realloc,free #include<assert.h>//assert #include<string.h>//memmove内存移动函数, //#define NDEBUG //可以对assert函数进行禁用; #define SEQ_INIT_SIZE 10 #define SEQ_SIZE 2 typedef int tempstyle; typedef struct { tempstyle* data; //数据域; int curpity; //链表的容量; int cursize; //链表的长度; }Seqlist; //功能模块化; //对链表进行动态空间的申请; Seqlist* INIT_list(Seqlist* plist)//顺序表初始化; { //对链表的容量进行赋值; plist->curpity = SEQ_INIT_SIZE; plist->cursize = 0; plist->data = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity); //申请动态存储空间; } //创建链表; void creatlist(Seqlist* plist, int n) { assert(plist != NULL); plist->cursize = n; for (int i = 0; i < n; i++) { scanf("%d", &plist->data[i]); } } //创建打印函数; void printlist(Seqlist* plist) { assert(plist != NULL); printf("输出链表:\n"); for (int i = 0; i < plist->cursize; i++) { printf("%5d", plist->data[i]); } putchar('\n'); } //判断是否已经满了; bool INIT_man(const Seqlist* plist) { assert(plist != NULL); if (plist->cursize < plist->curpity) { return false; } else return true; } //创建插入函数; bool insert_list(Seqlist* plist, int pos, tempstyle val) { assert(plist != NULL); if (pos<0 || pos>plist->cursize) { return false; } if (INIT_man(plist) == true) { return false; } else { for (int i = plist->cursize; i > pos; i--) { plist->data[i] = plist->data[i - 1]; } plist->data[pos] = val; plist->cursize += 1; return true; /* for(int i=plist->cursize-1;i>=pos;i--) { plist->data[i+1]=plist->data[i]; } plist->data[pos]=val; plist->cursize+=1; return true; */ } } //查找函数,对输入的值进行查找; int FIND_list(Seqlist* plist, tempstyle val) { assert(plist != NULL); int pos = plist->cursize; while (pos > 0 && plist->data[pos - 1] != val) { pos--; } if (pos == 0) return -1; else return pos; } //判断链表是否为空; bool INIT_kong(const Seqlist* plist) { assert(plist != NULL); if (plist->cursize == 0) return true; else return false; } //增加扩容; bool INIT_seqlist(Seqlist* plist) { assert(plist != NULL); int total; total = plist->curpity * SEQ_SIZE; tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * total); if (plist == NULL) { return false; } else { /* for(int i=0;i<plist->curpity;i++) { newnode[i]=plist->data[i]; } memmove(newnode,plist->data,sizeof(tempstyle)*plist->curpity); free(plist->data); plist->data=newnode; plist->curpity=total; return true;*/ plist->data = (tempstyle*)realloc(plist->data, sizeof(tempstyle) * total);//增加到tatol的空间; plist->cursize += 1; plist->curpity = total; return true; } } //尾部插入; void insert_back(Seqlist* plist, tempstyle val) { assert(plist != NULL); //也可以调用函数,进行插入; insert_list(plist, plist->cursize, val); /* plist->data[plist->cursize]=val; plist->cursize+=1; */ } //头部插入; void insert_front(Seqlist* plist, tempstyle val) { assert(plist != NULL); insert_list(plist, 0, val); /* for(int i=plist->cursize;i>0;i--) { plist->data[i]=plist->data[i-1]; } plist->data[0]=val; plist->cursize+=1; */ } void makemenu() { printf("\t创建循环链表:\n"); putchar('\n'); printf("\t输入你要输入的值:\n"); putchar('\n'); printf("\tn代表链表的长度,val1代表头插入的值,val2代表尾插入的值:\n"); putchar('\n'); printf("\t你可以输入pos的值来删除函数中指定位置的数据:\n"); putchar('\n'); } //求出链表还差多少字节才能满; int LENGTH_list(Seqlist* plist) { assert(plist != NULL); if (plist->cursize == plist->curpity) { printf("链表已经满了:\n"); } else return plist->curpity - plist->cursize; } int length_list(Seqlist* plist) { assert(plist != NULL); return plist->cursize; } //指定位置删除; bool delete_list(Seqlist* plist, int pos) { assert(plist != NULL); //需要判断输入的位置是否存在; if (pos > 0 && pos <= plist->cursize) { for (int i = pos - 1; i <= plist->cursize - 1; i++) { plist->data[i] = plist->data[i + 1];//最后一个给了空值; } /* for(int i=pos;i<plist->cursize;i++) { plist->data[i-1]=plist->data[i]; } */ plist->cursize -= 1; return true; } else return false; } //判断一个值是否在这个表中; bool ADJUST_list(Seqlist* plist, tempstyle val) { assert(plist != NULL); int cnt = 0; for (int i = 0; i < plist->cursize; i++) { if (plist->data[i] == val) { cnt++; } } if (cnt >= 1) return true; else return false; } //删除你想删除的值; int delete_val_list(Seqlist* plist, tempstyle val)//状态返回; { assert(plist != NULL); return delete_list(plist, FIND_list(plist, val)); } //摧毁函数; void destroy_list(Seqlist* plist) { plist->curpity = 0; plist->cursize = 0; free(plist->data); } //链表重置为空; void clear_list(Seqlist* plist) { assert(plist != NULL); plist->cursize = 0; } //删除链表中所有等于val的值; /*void delete_all_list(Seqlist*plist,tempstyle val) { assert(plist!=NULL); int pos; while(pos=FIND_list(plist,val)!=-1) { delete_list(plist,pos); } } */ /*void delete_all_list(Seqlist*plist,tempstyle val) { assert(plist!=NULL); int j=-1; int i=0; for(i;i<plist->cursize;++i) { if(plist->data[i]!=val) { j+=1; plist->data[j]=plist->data[i]; } } plist->cursize=j+1; }*/ void delete_all_list(Seqlist* plist, tempstyle val) { assert(plist != NULL); tempstyle* newnode = (tempstyle*)malloc(sizeof(tempstyle) * plist->curpity); int i = 0; for (int j = 0; j < plist->cursize; j++) { if (plist->data[j] != val) { newnode[i] = plist->data[j]; i++; } } memmove(plist->data, newnode, i); plist->cursize = i; } //创建主函数; int main() { Seqlist* plist; int n; int m; int pos; tempstyle val1, val2, val3; system("color 05"); makemenu(); scanf("%d", &n); INIT_list(plist); if (n > 10) { INIT_seqlist(plist); } creatlist(plist, n); printlist(plist); printf("\t输入你要插入的值:\n"); scanf("%d", &val1); insert_front(plist, val1); printlist(plist); printf("\t输入你要插入的值:\n"); scanf("%d", &val2); insert_back(plist, val2); printlist(plist); printf("链表的长度为:\n"); printf("%d\n", length_list(plist)); if (INIT_man(plist) == true) { printf("\t链表已经满了:\n"); return 0; } if (INIT_kong(plist) == true) { printf("\t链表为空:\n"); } m = LENGTH_list(plist); printf("\t链表还差%d才会满:\n", m); printf("\t判断链表中是否有你输入的值:\n"); scanf("%d", &val3); if (ADJUST_list(plist, val3) == true) { printf("\t有你要查找的数:\n"); } printf("\t现在可以进行删除函数:\n"); printf("输入n你要删除的数据的位置:\n"); scanf("%d", &pos); delete_list(plist, pos); printf("删除后的链表的长度为:\n"); printf("%d", length_list(plist)); printlist(plist); tempstyle val4; printf("\t删除链表中所有指定的值:\n"); scanf("%d", &val4); delete_all_list(plist, val4); printlist(plist); putchar('\n'); m = LENGTH_list(plist); printf("\t链表还差%d才会满:\n", m); //destroy_list(plist); return 0; return 0; }
总结
顺序表想比单链表有操作简单,无需更多的内存空间,查询数据简单。但是链表的长度不容易控制,每次插入数据需要移动大量数据,容易造成数据遗失。