zoukankan      html  css  js  c++  java
  • 线性表的顺序存储结构

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

    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;
    }
    
    
    
  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/strator/p/7216172.html
Copyright © 2011-2022 走看看