• 数据结构——数组


    说明:严蔚敏的《数据结构》(C语言版)学习笔记,记录一下,以备后面查看。


    ElemType *elem记录第一个元素的地址,也就是数组的首地址(基地址)

    int length 是实际数组中数据的长度

    int listsize 是给数组分配的空间长度

    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h>
    
    #define LIST_INIT_SIZE  100  //线性表存储空间的初始分配量
    #define LISTINCREMENT   10   //线性表存储空间的分配增量
    const int OK = 1;  //定义正确返回
    const int ERROR  = -1;  //定义错误的返回
    const int OVERFLOW = -2; //定义溢出
    
    //定义元素类型
    typedef int ElemType;
    //定义返回类型
    typedef int Status;
    //定义一个线性的数组结构
    typedef struct{
    	ElemType *elem;  
    	int length;
    	int listsize;
    } SqList;
    
    //初始化列表
    Status InitList_Sq(SqList &L){
    	//构造一个空的线性表L
    	L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    	if(!L.elem) exit(OVERFLOW); //存储分配失败
    	L.length = 0; //实际元素长度是0
    	L.listsize = LIST_INIT_SIZE;//分配的长度(字节)
    	return OK;
    }
    
    //插入元素
    //插入数组中下标为i的位置
    Status ListInsert_Sq(SqList &L, int i, ElemType e){
    	ElemType *newbase;
    	//在顺序线性表L中第i个位置之前插入新的元素e
    	if(i<1 || i>L.length+1) return ERROR;  //i 值不合法
    	if(L.length >= L.listsize){ //如果数组元素满了就扩展
    		newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
    		if(!newbase) exit(OVERFLOW);
    		L.elem = newbase; //新基址
    		L.listsize += LISTINCREMENT; //增加存储容量
    	}  
    	ElemType *q = &(L.elem[i - 1]); //取到数组中第i个元素的地址赋给指针q
    	ElemType *p;
    	//从i+1元素位置开始向后移动元素
    	for(p = &(L.elem[L.length - 1]); p>=q; --p) *(p+1) = *p;
    	*q = e;
    	++L.length;
    	return OK;
    }
    
    //添加元素
    Status ListAdd_tail(SqList &L, ElemType e){
    	ElemType *newbase;
    	if(L.length >= L.listsize){
    		newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
    		if(!newbase) exit(OVERFLOW);
    		L.elem = newbase;
    		L.listsize += LISTINCREMENT;
    	}
    	L.elem[L.length] = e;
    	++L.length;
    	return OK;
    }
    
    //删除元素
    ElemType ListRemove_Sq(SqList &L, int i){
    	if(i<0 || i>=L.length) return ERROR;
    	ElemType *p;
    	//将第i个元素后面的所有元素向前移动一位
    	for(p = &(L.elem[i]); p<&(L.elem[L.length - 1]); ++p) *p = *(p+1);
    	--L.length;
    	return OK;
    }
    
    //遍历元素
    void showList(const SqList &L){ 
    	int i;
    	for(i=0; i<L.length; i++){
    	   printf("%d
    ", L.elem[i]);
    	}
    }
    
    int main(){
    	SqList sq;
    	InitList_Sq(sq);
    	ElemType et1 = 3;
    	ElemType et2 = 4;
    	ListInsert_Sq(sq,1,et1);
    	ListInsert_Sq(sq,2,et2);
    	ListAdd_tail(sq, et1);
    	ListAdd_tail(sq, et1);
    	ListAdd_tail(sq, et1);
    	ListAdd_tail(sq, et2);
    	ListRemove_Sq(sq, 1);
    	showList(sq);
    	scanf("%d");
    	return 0;
    }

    值得思考的问题:

    1、为什么传引用?

    2、什么时候应该什么成const?

    3、结构体的初始化

    4、静态存储区和动态存储区的特点和区别


  • 相关阅读:
    多点触摸的一些代码
    精灵跳跃练习
    svn安装所遇到的几个问题[转载]
    简易包边字画法
    http和socket简介
    ant使用笔记
    j2se图片拖拽练习
    A星寻路示例
    迅为瑞芯微iTOP3399开发板资料更新
    迅为i.MX6Q开发板NXP恩智浦ARM安卓linux开发板
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468683.html
Copyright © 2020-2023  润新知