严蔚敏数据结构部分代码C/C++表示

一、说明

预定义常量及类型:

//函数结果以及状态码
#define OK    1
#define ERROR 0
#define OVERFLOW -2

//Status 为int类型(函数返回值),值为状态码。
tpyedef int Status;
函数类型函数名(函数参数表)
{
//算法说明
        语句序列
}/ /函数名

内存动态分配与释放

使用 new delete 动态分配和释放内存空间:
分配空间 指针变扯 =new 数据类型;
释放空间 delete 指针变扯;

输入输出语句使用 C++流式输入输出的形式:

输入语句:
cin>> 变拭 l>> >>变扯 n;
输出语句:
cout<< 表达式 l<< <<表达式 n;

线性表的操作类型:

ADT List{
数据对象 D={ai I aiEElemSet, i=l, 2, …, n, n;;,,Q}
数据关系: R={<ai-1,ai>|ai-1,a 1,aiED, i=2, …, n}
基本操作:
Ini tList (&L)
操作结果:构造一个空的线性表L。
DestroyList(&L)
初始条件:线性表L已存在。
操作结果:销毁线性表L。
ClearList (&L)
初始条件:线性表L已存在。
操作结果:将L重置为空表。
初始条件:线性表L已存在。
操作结果:若L为空表, 则返回true, 否则返回false。
ListLength(L)
初始条件:线性表L已存在。
操作结果:返回L中数据元素个数。
GetElem(L,i,&e)
初始条件:线性表L巳存在,且1:,s;i:os;ListLength(L)。
操作结果:用e返回L中第1个数据元素的值。
LocateElem(L,e)
初始条件:线性表L已存在。
操作结果:返回L中第1个 值与e相同的元素在 L中的位置 。若这样的数据元素不存在 , 则返回值为0。
PriorElem(r,,cur_e,&pre_e)
初始条件:线性表L已存在。
操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回其前驱,否则操作失败,pre_e无定义。
NextElem(L,cur_e,&next_e)
初始条件:线性表L已存在。
操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回其后继,否则操作失败,next_e无定义。
Listinsert(&L,i,e)
初始条件:线性表L已存在,且1:,s;i:os;ListLength (L) +l。
操作结果:在 L中第1个位置之前插入新的数据元素 e, L的长度加1。
ListDelete(&L,i)
初始条件:线性表L已存在且非空 ,且l:os;i:os;ListLength(L)。
操作结果:删除L的第1个数据元素,L的长度减1。
TraverseList(L)
初始条件:线性表L已存在。
操作结果:对线性表L进行遍历,在遍历过程中对 L的每个结点访问一次。
) ADT List
假设线性表的每个元素需占用l个存储单元, 并以所占的第一个单元的存储地址作为数据元
素的存储起始位置。则线性表中第i+ 1个数据元素的存储位置LOC(ai+ 1 )和第i个数据元素的存
储位置LOC(a;)之间满足下列关系:
一般来说, 线性表的第l个数据元素a;的存储位置为:
LOC(ai) = LOC(a 1 ) + (i - I) x l
式中,LOC(a 1 )是线性表的第一个数据元素a 1 的存储 位置, · 通常称作线性表的起始位置或基地址, 表中相 邻的元素a; 和a; + I 的存储位置LOC(a;)和LOC(a;+ 1) 是相邻的。

顺序表存储结构(通常采用数组来描述数据结构中的顺序存储结构)

1.定义结构体

        严蔚敏书中代码

#define MAXSIZE 100     //顺序表可能达到的最大长度,数组空间大小
typedef int ElemTpye;  //为int起个别名为ElemType
typedef struct 
{ 
    ElemType *elem;    //存储空间的基地址
    int length;        //当前的长度

 }SqList;              //顺序表的结构类型为SqList
        常规代码 1        
#define MAXSIZE 100
typedef struct{
	ElemType *elem;    //存储空间的基地址
	int MAXSIZE        //容量
	int length;        //当前长度
	}SqList

        常规代码 2

typedef struct {

   int *elem;
   int MaxSize,length;
}SqList;

        常规代码 3

#define MAX_SIZE 100                     //数组最大长度
typedef int ElemType                     //数据类型的别名
typedef struct sqlist                    //定义结构体
{
        Elemtype data[MAX_SIZE];         //线性表存储元素的数组
        int length;                      //记录线性表长度
}SqList;                                 //线性表名称

2.初始化
补充:代码中有几个点需要说明
数组静态分配
typedef struct 
{
    ElemType data[MAXSIZE];
    int length;
}SqList;
数组动态分配
typedef struct 
{
    ElemType *data;
    int length;
}SqList;

C语言的内存动态分配

SqList L;

L.data=(ElemType *)malloc(sizeof(Elemtype)*MAXSIZE);
malloc(m):开辟m字节长度地址空间,并返回空间首地址。
sizeof(x):计算变量x的长度。
free(p):释放指针P所指变量的存储空间,彻底删除。
        
难理解的等价的写法:

*是根据地址找变量,比如*a表示获取地址为a的变量。注意,这里的a是一个地址。

&是根据变量找地址,比如&a表示获取变量a的地址。而这里的a就表示变量本身。

但初始化时要注意

int *a=b 这是指针初始化操作,是把b赋值给a,因为a表示一个地址,所以b必须是一个地址。

int &a=b 这是引用的初始化操作,是将b赋值给a,因为a是一个变量,所以b必须是一个变量。

int b=10;

int *a=&b;                //*a=20,则b=20

//为顺序表分配空间 

注意&L与*L的用法:(*L).elem = L->elem;
语法规定:
int b=10;
int *a=&b                                      //将

#define MAXSIZE 10                        //数组长度为10
typedef struct
{
	int *elem;                                            //存储空间的基地址
	int MAXSIZE                                           //容量
}SqList

int InitList(SqList &L)
{
L.elem=(int*)malloc(MAXSIZE*sizeof(int));
}



#define MAX_SIZE 10                        //数组长度为10
typedef struct  
{
	int* elem;                                            //基地址,动态方式
    int  data[MAX_SIZE];                                  //静态方式

} SqList;

写法1:
int InitList(SqList* L)
{
int* temp = (int*)malloc(MAX_SIZE*sizeof(int));    //temp为临时变量,赋值给data
}
L->elem=temp;

写法2:
int InitList(SqList* L)
{
SqList*L->data=(int*)malloc(sizeof(int)*MAX_SIZE);
}

写法3:
int InitList(SqList* L)
{
(*L).elem =(int *)malloc(sizeof(int)*MAX_SIZE);  //写法等价(*L).elem = L->elem;
}

//结构体指针和结构体变量
例:指针P表示结点。如描述指针P(并非是说指针域,而是指代P所指向的节点)
       如果使用结点q,那么访问数据域和指针域的代码为q.data,q.next。
       如果使用指针p,那么访问数据域和指针域的代码为p->data,p->next。
        
        C++代码
Status InitList(SqList &L) 
{                                  //构造一个空的顺序表L并初始化

L.elem= new ElemType[MAXSIZE];     //为顺序表分配一个大小为MAXSIZE的数组空间
    if (!L. elem){
        exit (OVERFLOW);          //存储分配失败退出
        L.length=O;               //空表长度为
}
return OK;
}

        常规代码 1

int InitList(SqList &L)
{
//构造一个空顺序表L

L.elem=(int*)malloc(MAXSIZE*sizeof(int));//分配int类型指针数组空间,成功返回首地址,失败返回NULL,为顺序表分配大小MAX_SIZE的数组空间

if(!L.elem)  
exit(-1);            //exit除0外的其它值为异常退出
L.length=0;          //空表长度为0
return Ok;            //#define OK 1
}

        常规代码 2

int InitList(SqList *L)     //结构体指针变量作为形参 
{     
    (*L).elem =(ElemType *)malloc(sizeof(ElemType)*MAXSIZE); //为顺序表分配空间

    if(!L->elem) exit(OVERFLOW);     //异常处理,存储分配失败
    L->length=0;                     //空表长度为0
    return OK; 
}

        常规代码 3

SqList*L->data=(int*)malloc(sizeof(int)*MAX_SIZE);  //为顺序表分配MAX_SIZE个空间
3.取值

        C++代码

Status GetElem(SqList L,int i,ElemType &e)
{ 
if (i<1 || i>L.length) return ERROR; //判断l. 值是否合理,若不合理, 返回 ERROR
e=L.elem[i-1];    //elem[i-1] 单元存储第 i 个数据元素 a(i)对应数组为i-1
return OK;
}

    常规代码 1

【算法步骤】
心判断指定的位置序号 i 值是否合理 (1<=i<=L.length), 若不合理,则返回ERROR。
若 i 值合理,则将第 i 个数据元素 L.elem[i-1]赋给参数 e, 通过 e返回第 1 个数据元素的
传值。

int GetElem(SqList L, int i, int& e)
{
	if (i < 1 || i > L.length)   //判断i的值是否合理(是否为负数或是否超出表长),不合理返回ERROR
	{
		printf("获取值失败!");
		exit(0);
	}

	e = L.elem[i - 1];  // elem[i - 1]单元存储第i个数据元素

	return e;
} 
4.查找
【算法步骤】
心从第一个元素起,依次和 e相比较,若找到与 e相等的元素 L.elem[i], 则查找成功,返回
该元素的序号 i+l。
@若查遍整个顺序表都没有找到,则查找失败, 返回0。
【算法描述】
int LocateELem(SqList L,ElemType e) 
{//在顺序表1中查找值为e的数据元素, 返回其序号
for(i=O;i< L.length;i++) 
if(L.elem[i)==e)                             //查找成功, 返回序号 i+l
return i+l;                                   //顺序表中位置比数组+1
return O;                                    //查找失败, 返回 0
}
5.插入
[算法步骤]
判断插入位置l是否合法(i 值的合法范围是1<=i<=n+1), 若不合法则返回 ERROR。
判断顺序表的存储空间是否已满,若满返回 ERROR。
将第n个至第l个位置的元素依次向后移动一个位置,空出第l个位置(i=n+1时无需
移动)。
将要插入的新元素e放入第i个位置。
表长加l。
【算法描述】
Status Listinsert(SqList &L,int i ,ElemType e) 
{
//在顺序表L中第i个位置之前插入新的元素e, i值的合法范围是 1<=i<=L.length+l 
if((i<l)||(i>L.length+l))                //i值不合法 
return ERROR; 
if(L.length==MAXSIZE)                    //当前存储空间已满 
return ERROR; 
for (j=L. length-1; j>=i-1; j--) 
L.elem[j+l]=L.elem[j];                    //插入位置及之后的元素后移
L.elem[i-l]=e;                            //将新元素e放入第l个位置
++L.length;                                //表长+1
return OK;

         常规代码1

方法一:数组法
Status Insert(SqList &L, int i, ElemType e) 
{
        //因为可以插在最后,所以i值的合法范围是 1~L.length+1
        if ((i < 1) || (i > L.length + 1)) 
            return ERROR;                       
        
        if (L.length >= L.listsize) //存储空间已满
        {
            ElemType *data;
            data =(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
            if(!data) return;
            L.elem = data;
            L.listsize += LISTINCREMENT;
        }          
 
        
        for (j = L.length-1; j >= i-1; j--)   //j=L.length-1表示从顺序表最后一个元素开始
        L.elem[j + 1] = L.elem[j];          //插入位置及之后的元素后移
        L.elem[i - 1] = e;                   //将新元素e放入第l个位置
        L.length ++;                                      
        return OK;
}

方法二:指针法

    ElemType *p = &(L.elem[i-1]); //指针p指向第i个元素
    ElemType *q = &(L.elem[L.length-1]); //指针q指向最后一个元素
    for(q ;q>=p;q--)
        *(q+1) = *q;
    *p = e;
    L.length++;



6.删除

删除第i(1<=i<=n) 个元素时需将第i+1个至第n 个元素(共 n-i 个元素) 依次向前移动一个位置
(i = n 时无需移动)

判断删除位置 i是否合法(合法值为1<=i<=n), 若不合法则返回 ERROR。
将第i+l个至第n个的元素依次向前移动一个位置 (i=n时无需移动)。
表长减1.

Status ListDelete(SqList &L,int i) 
{
//在顺序表L中删除第i个元素,i值的合法范围是 1<=i<=L.length 
if((i<l)||(i>L.length)) return ERROR;        //i值不合法
for (j=i;j<=L.length-1;j ++) 
    L.elem[j-1]=1.elem[j];                    //被删除元素之后的元素前移
--l.length;                                   //表长减1
return OK;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值