• 线性表的顺序存储结构


    顺序存储结构封装需要三个属性:

    1.存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置
    2.线性表的最大存储容量,数组的长度MaxSize
    3.线性表的当前长度:length

    当前长度与数组长度区别:数组长度就是该顺序表的总长度,如果不进行扩容的话,就是不变的。而当前长度在数据的变化中,就会发生相应的变化。

    PS:线性表是正常的读数方法,一下标1开始的。

    存储时间性能:O(1)

    性能:存取以及读取不管是在哪个位置,其时间复杂度都是O(1),而在插入还是删除其时间复杂度都是O(n)

    结论:比较适合数据的存取而不适合经常性增删的情况。

    顺序存储结构的优缺点

    1.优点:
    - 无须为表示表中元素之间的逻辑关系而增加额外的存储空间
    - 可以快速的存取表中任意位置的元素。
    2.缺点:
    - 插入以及删除操作需要移动大量的元素。
    - 当线性表长度变化较大时,难以确定存储空间的容量。
    - 容易造成存储空间的碎片。

    具体代码的实现:

    // 头文件部分,进行常量参数初始化
    #define LIST_INT_SIZE 10  //线性顺序表初始动态分配内存大小
    #define INCREAMENT 2    //线性表扩容一次性增量
    #define    OK      1
    #define   ERROW   -1
    #define  OVERFLOW -2
    
    
    #include<stdio.h>
    #include <stdlib.h>//malloc函数包含在其中
    
    
    typedef int Elemtype;     //线性表的数据类型
    typedef int Status;      // 状态数据类型
    // 顺序表存储结构定义
    typedef struct {
    	Elemtype *elem;      //定义线性表内数据元素的数据类型
    	int length;          //表当前长度
    	int listsize;        //表当前空间容量大小
    } SqList;                //表名
    // 初始化一个顺序表
    Status InitList(SqList &L) {
    	L.elem = (Elemtype *)malloc(LIST_INT_SIZE * sizeof(Elemtype)) ;//动态分配内存,分配后可以将l.elem作为数组使用
    	if(!L.elem) {                    //对内存分配的结果判断
    		exit(OVERFLOW);
    	}   //这个地方可以去查一下资料
    //	if(L.elem == NULL) {
    //		printf("分配内存失败")
    //		exit(1);
    //	}
    	//关于内存分配结果的判断,又该如何去进行判断
    	//这种方法进行判断又是否正确
    	L.length = 0;                      //对表长初始化归0
    	L.listsize = LIST_INT_SIZE;
    	return OK;
    }
    
    // 创建一个顺序表
    Status CreateList(SqList &L) {
    	int i;
    	InitList(L);
    	printf("请输入元素个数:
    ");
    	scanf("%d",&L.length);
    	printf("
    请输入您要输入的元素
    ");
    	for(i=0; i<L.length; i++) {
    		scanf("%d",&L.elem[i]);
    	}
    	printf("顺序表已创建成功,打印表请选择功能 *3
    ");
    	return OK;
    }
    // 顺序表的遍历
    Status TraverseList(SqList &L) {
    	int i;
    	printf("表中元素为:
    ");
    	for(i=0; i<L.length; i++)
    		printf("%d  ",L.elem[i]);
    	printf("
    
    顺序表输出完毕!
    ");
    }
    //顺序表的插入
    // 表L 位置 i  Elemtype  要插入的元素
    Status InsertList(SqList &L,int i,Elemtype e) {
    	int* newbase;
    	int j;
    	if(i < 1 ||i > L.length+1) {   // 判断所要插入的位置
    		return ERROW;
    	}
    	if(L.length>=L.listsize) {
    		newbase = (Elemtype*)realloc(L.elem,(L.listsize+INCREAMENT)*sizeof(Elemtype));
    		if(!newbase) {
    			exit(OVERFLOW);
    		}
    		L.elem = newbase;
    		L.listsize += INCREAMENT;
    	}
    	for(j = L.length-1; j>i-1; j--) {
    		L.elem[j+1]=L.elem[j];
    	}
    	L.elem[i-1] = e;
    	L.length++;
    	return OK;
    }
    //删除指定位置元素并返回出来
    Status deleteListElem(SqList &L,int i) {
    	Elemtype e;
    	int j;
    	if(i<1 || i>L.length) {
    		return ERROW;
    	}
    	e = L.elem[i-1];
    	for(j = i-1 ; j<=L.length; j++) {
    		L.elem[j] = L.elem[j+1];
    	}
    	L.length--;
    	return e;
    }
    //判断一个值是不是线性表中的元素并返回第几个元素
    Status ifElemExit(SqList &L,Elemtype e) {
    	int i = 0;
    	for(; i<L.length; i++) {
    		if(e==L.elem[i])
    			break;
    	}
    	if(i>=L.length) {
    		return ERROW;
    	} else {
    		return i;
    	}
    }
    
    //输出一个位置的数据元素
    Status GetElem(SqList &L,int i) {
    	if(i<1||i>L.length) {
    		return ERROW;
    	}
    	return L.elem[i-1];
    }
    //根据元素的值来进行删除
    Status deleteElemByR(SqList &L,Elemtype e) {
    	int i = 0;
    	i = ifElemExit(L,e);
    	if(i==-1) {
    		printf("该值不再线性表中:");
    		return ERROW;
    	} else {
    		deleteListElem(L,i+1);
    		printf("删除成功!删除的是位置为%d,值为%d",i,e);
    		return OK;
    	}
    }
    //将线性表进行递减排序操作
    Status SortByMao(SqList &L) {
    	Elemtype e;
    	for(int j=0; j<L.length; j++) {
    		for(int i=0; i<L.length-i-j; i++) {
    			if(L.elem[i]<L.elem[i+1]) {
    				e = L.elem[i];
    				L.elem[i] = L.elem[i+1];
    				L.elem[i+1]=e;
    			}
    		}
    	}
    }
    void UnionTwo(SqList &la,SqList &lb) {
    	
    	int la_length = la.length;
    	int lb_length = lb.length;
    	for(int i=1;i<=lb.length;i++){
    		Elemtype e= GetElem(Lb,i);
    		if(ifElemExit(La,e)==-1){
    			InsertList(La,la_length,e);
    			la_length++;
    			la.length++;
    		}
    	}
    	
    	
    	
    } 
    
    
    /***主提示输出函数***/
    
    
    void printlin() {
    	printf("
    ");
    	printf("			线性顺序表基本操作学习系统
    ");
    	printf("			      ***主菜单***
    
    ");
    	printf("			    *1 创建一个顺序表
    ");
    	printf("			    *2 定位输出一个数据元素
    ");
    	printf("			    *3 输出顺序表中所有元素
    ");
    	printf("			    *4 定位插入一个数据元素
    ");
    	printf("			    *5 定位删除一个数据元素
    ");
    	printf("			    *6 定值删除一个数据元素
    ");
    	printf("			    *7 清空顺序表
    ");
    	printf("			    *8 销毁顺序表
    ");
    	printf("			    *9 对表内数据元素进行非递减排序
    ");
    	printf("			    *0 结束程序
    ");
    }
    //清空线性表
    void clearList(SqList &L) {
    	if(L.length!=0) {
    		L.length = 0;   //由于顺序表的用得是与数组一样的内存空间,
    		//所以标的清空只要将表长归零即可,由此可见,表长是线性表非常重要的部分
    	}
    }
    //销毁线性表
    void destoryList(SqList &L) {
    	if(L.length!=0) {
    		free(L.elem);
    		L.elem = NULL;//使用free后就需要对元素进行赋空操作
    	}
    
    }
    
    
    
    int main() {
    	int i,j,k;
    	Elemtype e;
    	SqList L;
    	L.length=0;
    	printf("编写此程序目的是自我学习线性表顺序表
    ");
    	printlin();
    	while(1) {
    		int t;
    		scanf("%d",&t);
    		if(t!=0)
    			if(t==1||L.length!=0) {
    				switch(t) {
    					case 1:
    						if(L.length!=0) {
    							printf("顺序表已存在,是否重新创建顺序表?
    ");
    							printf("*1 是   *2 否
    ");
    							scanf("%d",&i);
    							if(i==1)
    								CreateList(L);
    						} else
    							CreateList(L);
    						break;
    					case 0:
    						break;
    					case 3:
    						TraverseList(L);
    						break;
    					case 7:
    						clearList(L);
    						printf("清空完毕,返回主菜单
    
    ");
    						break;
    					case 4:
    						printf("输入要插入的位置
    ");
    						scanf("%d",&i);
    						printf("请输入要插入的数据
    ");
    						scanf("%d",&j);
    						k=InsertList(L,i,j);
    						if(k==-1) {
    							printf("插入位置不合法,插入数据操作失败!
    
    ");
    						} else
    							printf("插入数据成功
    
    ");
    						break;
    					case 5:
    						printf("请输入要删除数据位置
    ");
    						scanf("%d",&i);
    						e = deleteListElem(L,i);
    						printf("删除掉的元素是第%d个位置,它的值是%d",i,e);
    						break;
    					case 2:
    						printf("请输入要需要得到数据位置:");
    						scanf("%d",&i);
    						e = GetElem(L,i);
    						printf("第%d个位置上的元素值为:%d",i,e);
    						break;
    					case 6:
    						printf("请输入需要删除的值:");
    						scanf("%d",&e);
    						deleteElemByR(L,e);
    						break;
    					case 8:
    						destoryList(L);
    						printf("销毁成功!");
    						break;
    					case 9:
    						SortByMao(L);
    						break;
    					default: {
    						printf("输入有误,可以重新选择,退出按0!
    ");
    					}
    				}
    			} else
    				printf("顺序表未创建或已清空或销毁,请先创建顺序表
    ");
    		system("pause");
    		system("CLS");
    		printlin();
    		if(t==0)
    			break;
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    react native android 应用状态(前端或后台)的判断
    react native native module
    Nodejs项目重复文件扫描
    clipboard.js文本复制到剪贴板的现代方法
    微信小程序如何跳转到另一个小程序
    百度小程序button去掉默认边框
    下拉框select中option居中样式
    css中如何实现左边的高度随着右边改变而改变
    js判断是否手机自动跳转移动端
    webpack安装整理
  • 原文地址:https://www.cnblogs.com/strator/p/7216172.html
Copyright © 2020-2023  润新知