王道数据结构代码笔记

本文详细介绍了数据结构的基础知识,包括数据结构的逻辑结构和存储结构,以及算法的效率度量。接着深入讲解了线性表的各种实现,如顺序表、单链表、双链表、循环链表和静态链表的操作。此外,还涵盖了栈、队列的实现,包括顺序栈、共享栈、链栈和循环队列。最后,文章提到了树与二叉树的概念,如二叉树的遍历和线索二叉树,并简单提及了图的存储结构和查找算法,如二叉排序树和平衡树AVL。
摘要由CSDN通过智能技术生成

知识点

1 绪论

1.1 数据结构的基本概念

1.1.1 基本概念和术语

数据:信息的载体

数据元素:数据的基本单位(整体考虑),由若干数据项(不可分割)组成。组合项:年月日等。

数据对象:具有相同性质的元素的集合,是数据的子集(性质相同:账号的集合)

数据结构:互相存在一种或多种特定关系的元素的集合(存在关系:财富排行榜)

数据类型

1.1.2 数据结构的三要素

逻辑结构独立于存储结构存储结构依赖于逻辑结构

逻辑结构:集合、线性结构(一对一)、树形结构(一对多)、图状结构或网状结构(多对多)
存储结构
描述 优点 缺点
顺序存储 逻辑相邻物理也相邻 随机存取
每个元素占用最少的空间
产生外部碎片
链式存储 不要求逻辑上相邻即物理相邻 不会产生碎片,充分利用存储空间 指针占用额外空间
只能顺序存取
索引存储 建立索引表(索引项) 检索速度快 索引表额外占用空间
修改索引表耗时
散列存储 根据关键字直接算出地址,又称哈希存储 检索、增加、删除节点都很快 散列函数不好时增加开销
运算

运算的__定义__是针对逻辑结构的,运算的实现是针对存储结构的。

1.2 算法和算法评价

1.2.1 算法的基本概念

算法是对特定问题求解步骤的描述,是指令的有限序列。

算法(有穷) <> 程序(无穷,微信可以一直运行)

程序 = 算法 + 数据结构 (算法独立于数据结构)

软件 = 程序 + 数据 + 文档

算法的特性:有穷性、确定性、可行性、输入、输出。

好的算法:正确性、可读性、健壮性、效率与低存储量需求

1.2.2 算法效率的度量

时间复杂度

空间复杂度

第二章 线性表

顺序表

SqList

//顺序表静态分配
#define MAxSize 50
typedef struct{
   
    ElemType data[MaxSize];
    int length;
}SqList;

void InitList(SqList &L)

//顺序表静态分配的初始化
void InitList(SqList &L){
   
    L.length=0;
}

SeqList

void InitList(SeqList &L)

void IncreaseSize(SeqList &L,int len)

//顺序表动态分配
#define InitSize 50
typedef struct{
    ElemType *data;
    int MaxSize,length;
}SeqList;
//顺序表动态分配的初始化
#define InitSize 10
void InitList(SeqList &L){
   
    L.data=(ElemType*)malloc(InitSize*sizeof(ElemType));
    L.length=0;
    L.MaxSize=InitSize;
}
//扩展动态数组
void IncreaseSize(SeqList &L,int len){
   
    int *p=L.data;//保存原指针
    L.data=(ElemType*)malloc((L.MaxSize + len) * sizeof(ElemType));
    for(int i=0; i<L.length; i++)//循环复制
    	L.data[i] = p[i];
    L.MaxSize += len;	//Size变大但len不变
    free(p);			//释放
}
int main(){
   
    SeqList L;//定义
    InitList(L);//初始化
    //..添加...
    IncreaseSize(L, 5);//扩展
    return 0;
}

bool ListInsert(SqList &L,int i,ElemType e)

//在位序为i的位置插入元素e
bool ListInsert(SqList &L,int i,ElemType e){
   
    if(i<1 || i>L.length + 1)		//判断位序合法
        return false;// i可以等于length+1(插在末尾)
    if(L.length>=MaxSize)			//判断空间没满
        return false;
   for(int j = L.length; j>=i; j--)
       L.data[j] = L.data[j-1];		//移动元素
    L.data[i-1]  = e;
    L.length++;					//长度++
    return true;
}

bool ListDelete(SqList &L,int i,ElemType &e)

//删除位序为i的元素,赋值给e
bool ListDelete(SqList &L,int i,ElemType &e){
   
    if(i<1 || i>L.length)			//判断位序合法
    	return false;
    e = L.data[i-1];				//赋值
    for(int j=i; j<L.length; j++)	//移动
        L.data[j-1] = L.data[j];
    L.length--;
    //长度--
    return true;
}

int LocateElem(SqList L,ElemType e)

//按值查找,返回位序
int LocateElem(SqList L,ElemType e){
   
    int i;
    for(i=0; i<L.length; i++)
        if(L.data[i] == e)return i+1;
    return 0;
}

ElemType GetElem(SqList L,int i)

ElemType GetElem(SqList L,int i){
   //按位查找,返回值
    if(i<1 || i>L.length)return false;	//判断合法
    return L.data[i-1];
}

单链表(带头结点)

LNode,*LinkList

typedef struct LNode{
   
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

bool InitList(LinkList &L)

//不带头结点
bool InitList(LinkList &L){
   
    L=NULL;
    return true;
}

//带头结点:
bool InitList(LinkList &L){
   //头结点不需要在main函数中分配
    L=(LNode*)malloc(sizeof(LNode));	//头结点
    if(L==NULL)return false;			//分配失败
    L->next=NULL;
    return true;
}

bool Empty(LinkList L)

bool Empty(LinkList L){
   
    return (L==NULL);//不带头结点
    return (L->next==NULL);//带头结点
}

LinkList List_HeadInsert(LinkList &L)

//头插法
LinkList List_HeadInsert(LinkList &L){
   
    LNode *s;
    int x;
    L=(LinkList)malloc(sizeof(LNode));	//头结点
    L->next=NULL;//头指针
    scanf("%d", &x);
    while(x!=9999){
   
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d", &x);
    }
    return L;
}

LinkList List_TailInsert(LinkList &L)

//带头结点
LinkList List_TailInsert(LinkList &L){
   
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    LNode *s, *r=L;//尾指针
    scanf("%d",&x);
    while(x!=9999){
   
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d",&x);
    }
    r->next=NULL;//置尾指针
    return L;
}

LNode *GetElem(LinkList L,int i)

//返回位序为i的节点的指针
LNode *GetElem(LinkList L,int i){
   
    int j = 1;
    LNode *p = L->next;
    //若为头结点,直接返回L
    if(i==0)return L;
    //小于0,不合法,返回NULL
    if(i<1)return NULL;
    //计数同时判非空,返回
    while(p!=NULL && j<i){
   
        p = p->next;
        j++;
    }
    return p;
}

LNode *LocateElem(LinkList L,ElemType e)

LNode *LocateElem(LinkList L,ElemType e){
   
    //判值同时判非空
}

bool ListInsert(LinkList &L,int i,ElemType e)

//按位序插入(调用)
bool ListInsert(LinkList &L,int i,ElemType e){
   //在位序i处插入e
    if(i<1)return false;
    LNode *p = GetElem(L,i-1);//找到前一个结点(若在不带头结点的链表的首部插入,需单独讨论)
    return InsertNextNode(p,e);//后插
}



//按位序插入(带头结点)
bool ListInsert(LinkList &L, int i, ElemType e){
   
    if(i<1)return false;//最小插入位置为1(位序)
    LNode *p;
    int j = 0;//第几个节点
    p = L;//遍历
    while(p!=NULL && j<i-1){
   //位序为i,则下标为i-1
        p = p->next;
        j++;
    }
    if(p==NULL)return false;//退出循环的原因是链表到头了
    LNode *s = (LNode*)malloc(sizeof(LNode));	//新节点
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

//按位序插入(不带头结点)
bool ListInsert(LinkList &L, int i, ElemType e){
   
    if(i<1)return false;
    if(i==1){
   //在首部插入单独考虑(操作不同)
        LNode *s = (LNode*)malloc(sizeof(LNode));
        s->data = e;
        s->next = L;	//这两行操作不同
        L = s;			//这两行操作不同
        return true;
    }
    LNode *p;
    int j = 1;//最开始就是第一个节点
    p = L;
    while(p!=NULL && j<i-1){
   
        p = p->next;
        j++;
    }
    if(p==NULL)return false;
    LNode *s = (LNode*)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

bool ListDelete(LinkList &L,int i,ElemType &e)

//删除位序i(带头结点)
bool ListDelete(LinkList &L,int i,ElemType &e){
   
    if(i<1)return false;
    LNode *p;
    int j = 0;
    p = L;
    while(p!=NULL && j<i-1){
   
        p = p->next;
       j++;
    }
    if(p==NULL)return false;//i非法
	LNode *q=p->next;
    e = q->data;
    p->next = q->next;
    free(q);
    return true;
}
//指定节点的删除(赋值后删后节点)
bool DeleteNode(LNode *p){
   
    if(p==NULL)return false;
    LNode *q = p->next;
    p->data = p->next->data;//************************p->next可能为空(p为尾结点)*******
    p->next = q->next;
    free(q);
    return true;
}

bool InsertNextNode(LNode *p,ElemType e)

bool InsertPriorNode(LNode *p,ElemType e)

bool InsertNextNode(LNode *p,ElemType e){
   
    if(p==NULL)return false;
    LNode *s = (LNode*)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值