数据结构代码笔记

2020-5-9 11:08:51

2.2.2 插入,删除.查找 Demo(由于没有学C/C++,代码就那个意思,理解就好)

插入

// 插入代码
#include <iostream> # define InitSize 10 //默认长度 typedef struct{ ElemType data[MaxSize]; //用静态的数组存放数据元素 int length; //顺序表的当前长度 }SqList; //插入操作(自己写的那种) L:表 i:元素位序 e:插入元素 bool ListInsert(SqList &L, int i, int e){ if(i<1||i>L.length+1) //判断i的范围是否有效 return false; if(L.length>=MaxSize) //当前存储空间已满,不能插入 return false; for(int j = L.length;j>=i; j--) //讲第i个元素及之后的元素后移动 L.data[j]=L.data[j-1]; L.data[i-1]=e; //在位置i处放入e L.length++; //长度加1 return true; } int main(){ SqList L; //声明一个顺序表 InitList(L); // 初始化顺序表 ListInsert(&L,1,0); //插入一个元素 ListInsert(&L,2,1); //插入一个元素 ListInsert(&L,1,3); }

按值查找

//顺序表的按值查找
#include <iostream>
typeef struct{
    int *data;        //指示动态分配数组的指针
    int MaxSize;    //顺序表的最大容量
    int length;        // 顺序表的当前长度
}SeqList

//在顺序表L中查找第一个元素值等于e的元素,并返回其位序
int LocateElem (SeqList L, int e){
    for(int i=0;i<L.length;i++)
        if(L.data[i]=e)
            return i+1;
    return 0;
}

int main(){
    SeqList(L);
    InitList(L);
    // 省略一些代码,插入一些数据
    LocateElem(L,3); // 查找元素值为3的元素
    
}

删除操作

//删除操作
#include <iostream>

# define   InitSize 10 //默认长度

typedef struct{
    ElemType  data[MaxSize];    //用静态的数组存放数据元素
    int length;                    //顺序表的当前长度
}SqList;

//删除操作(自己写的那种) L:表  i:元素位序  e:插入到的位置
bool ListDelete(SqList &L, int i , int &e){
    if|(i<1||i>L.length)    //    判断i的范围是否有效
        return false;        
    e=L.data[i-1];            // 将被删除的元素赋值给e
    for(int j=i; j<L.length;j++)    //将第i个位置后的元素前移
        L.data[j-i]=L.data[j]; //主义位序,数组下标的关系,并从前面的元素依次移动
    L.length--;    //线性表长度减1
    return true;
}

int main(){
    SqList  L;            //声明一个顺序表
    InitList(L);    // 初始化顺序表
    // ......此处省略一些代码,插入几个元素
    int e = -1;
    if(Listdelete(L,3,e))
        printf("已删除第3个元素,删除元素只为=%d\n",e);
    else
        printf("位序i不合法,删除失败\n");
}

 查找

// 查找方法
#include <iostream>
//定义一个表
typedef struct{
    ElemType  data[MaxSize];    //用静态的数组存放数据元素
    int length;                    //顺序表的当前长度
}SqList;

// 查找第几个元素
ElemType GetElem(SqList L, int i){
    return L.data[i-1]  //直接通过下标找元素
}
int main(){
    SqList  L;            //声明一个顺序表
    InitList(L);    // 初始化顺序表
    // ..省略一些代码,插入一些数据
    GetElem(&L,1);    //插入一个元素  

}

 2.3.1单链表的一些demo

1.不带头结点的单链表

#不带头结点的单链表
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

// 初始化一个空的单链表
bool InitList(LinkList&L){
    L = NULL;    //空表,暂时还没有任何结点 (防止脏数据)
    return true;
}

//判断单链表是否为空
bool Empty(LinkList L){
    if (L == null)
        return true;
    else
        return false;
}
//或者更简单
bool Empty(LinkList L){
    return (L== NULL);
}


int main(){
    LinkList L;        //声明一个指向单链表的指针
    InitList(L);    //初始化一个空表
    // ....后续代码
    
}

2.带头结点的单链表 (推荐使用,写代码更加方便)

//带头结点的单链表
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

// 初始化一个空的单链表(带头结点)
bool InitList(LinkList&L){
    L = (LNode *) malloc(sizeof(LNode));    //分配一个头结点
    if (L==NULL)        //内存不足,分配失败
        return false ;
    L->next = NULL;        // 头结点之后暂时还没有节点
    return true;
}

//判断单链表是否为空
bool Empty(LinkList L){
    if (L->next == null)
        return true;
    else
        return false;
}


int main(){
    LinkList L;        //声明一个指向单链表的指针
    InitList(L);    //初始化一个空表
    // ....后续代码
    
}

3.按位序插入(带头结点)

//按位序插入(带头结点)
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

// 在第i个位置插插入元素e(带头结点)
bool ListInsert(LinkList &L, int i ,ElemType e){
    // 找出 p点指针,也就是要插入的位置在位序为第i-1结点
    if(i<1);
        return false;
    LNode *p;    //指针p指向当前扫描到的结点
    int j = 0;    //当前p指向的第几个结点
    p = L         //L指向头结点,头结点是第0个结点(不存数据)
    while (p!=NULL && j<i-1){ // 循环找到第 i-1 个结点
        p=p->next;
        j++;
    }
    if(p==NULL)    //i值不合法
        return false;
    
    // 要在第i-1的结点之后插入一个新的结点
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next=p->next;//用s指向后面指针替换了p点指向后面的指针
    p->next=s        //将结点s链接到p之后
    return true;    //插入成功
}



int main(){
    LinkList L;        //声明一个指向单链表的指针
    InitList(L);    //初始化一个空表
    // ....后续代码
    
}

4.按位  序插入(不带头结点)

#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

// 在第i个位置插插入元素e(带头结点)
bool ListInsert(LinkList &L, int i ,ElemType e){
    // 找出 p点指针,也就是要插入的位置在位序为第i-1结点
    if(i<1);
        return false;
    if(i==1){    //插入第1个结点的操作与其他结点操作不同
        LNode *s = (LNode *)malloc(sizeof(LNode));
        s->data = e;
        s->next = L;
        L = s;    //头指针指向新结点
        return true;
    }
    LNode *p;    //指针p指向当前扫描到的结点
    int j=1;    //当前p指向的第几个结点
    p = L;        //p指向第1个结点(注意:不是头结点)
    while (p!=NULL && j<i-1){ //循环找到第 i-1个结点
        p=p->next;
        j++;
    }
    if(p==NULL)    //i的值不合法
        return  false;
    
    // 要在第i-1的结点之后插入一个新的结点
    // 插入逻辑和带头结点的一样,只是加了上面i=1的判断
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next=p->next;//用s指向后面指针替换了p点指向后面的指针
    p->next=s        //将结点s链接到p之后
    return true;    //插入成功
}


int main(){
    LinkList L;        //声明一个指向单链表的指针
    InitList(L);    //初始化一个空表
    // ....后续代码
    
}

5. 指定结点的后插操作

//按位序插入(不带头结点)
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名


// 指定结点的后插操作,  直接把原来插入逻辑解耦了一下
bool  InserNextNode(LNode *p, ElemType e){
    if(p==NULL)    //i的值不合法
    return  false;
    
    // 要在第i-1的结点之后插入一个新的结点
    // 插入逻辑和带头结点的一样,只是加了上面i=1的判断
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next=p->next;//用s指向后面指针替换了p点指向后面的指针
    p->next=s        //将结点s链接到p之后
    return true;    //插入成功
}

// 在第i个位置插插入元素e(带头结点)
bool ListInsert(LinkList &L, int i ,ElemType e){
    // 找出 p点指针,也就是要插入的位置在位序为第i-1结点
    if(i<1);
        return false;
    if(i==1){    //插入第1个结点的操作与其他结点操作不同
        LNode *s = (LNode *)malloc(sizeof(LNode));
        s->data = e;
        s->next = L;
        L = s;    //头指针指向新结点
        return true;
    }
    LNode *p;    //指针p指向当前扫描到的结点
    int j=1;    //当前p指向的第几个结点
    p = L;        //p指向第1个结点(注意:不是头结点)
    while (p!=NULL && j<i-1){ //循环找到第 i-1个结点
        p=p->next;
        j++;
    }
    return InsertNextNode(p,e);
}


int main(){
    LinkList L;        //声明一个指向单链表的指针
    InitList(L);    //初始化一个空表
    // ....后续代码
    
}

6.指定结点的前插操作

//指定结点的前插操作
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

//直接写 前插操作逻辑

//前插操作: 在p结点之前插入元素e
bool InsertPrioNode (LNode *p, ElemType e){
    if (p==NULL)
        return false;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if(s==NULL)         //内存分配失败
        return false;
    s->next = p->next;
    p->next = s;        //新结点s链接到p之后
    s->data = p->data;    //将p中元素复制到s中
    p->data = e;        // p中元素覆盖为e
    return true;        
}

//王道书里面的,直接给穿了  LNode *s
bool InserPriorNode(LNode*p, LNode *s){
    if(p==NULL || s==NULL)
        return false;
    s->next = p->next;
    p->next = s;         // s练到p之后
    ElemType temp = p->next;    //交换数据域部分
    p->data = s->data;
    s-data = temp;
    return true;
    

}

7.按位序删除(带头结点)

//按位序删除(带头结点)
#include <iostream>
typedef struct LNode{    // 定义单链表节点类型
    ElemType data;        // 每个节点存放一个数据元素
    struct LNode *next;    // 指针指向下一个节点
}LNode, *LinkList;        // 通过typedef函数,定义的链表和结点别名

bool ListDelete(LinkList &L, int i , ElemType &e){
    if (i<1)
        return false;
    LNode *p;            // 指针p指向当前扫描到的结点
    int j = 0;            // 当前p指向的第几个结点
    p = L;                // L指向头结点,头结点是0个结点(不存数据)
    while (p!NULL && j<i-1) {    // 循环找到第i-1个结点
        p = p->next;
        j++;
    }
    if(p == NULL)        // i值不合法
        return false;
    if(p->next == NULL)    //第i-1个结点之后已无其他结点
        return false;
    
    LNode *q = p->next;    //令q指向被删除结点
    e = q->data;        // 用e返回元素的值
    p->next = q->next;    //将*q结点从链中"断开"
    free(q);            // 释放结点的存储空间
    return true;        // 删除成功

}

8.指定结点的删除

bool DeleteNode(LNode *p){
    if (p== NUll)
        return false;
    LNode *q = p->next;            // 令q指向*p的后继结点
    p->data = p->next->data;    // 和后继结点交换数据域
    p->next = q->next;            // 将*q结点从链中"断开"
    free(q);                    // 释放后继结点的存储空间
    return true;
}

2020-5-9 21:07:59 先写到这,写了一天代码,感觉还是很充实

2020-5-10 19:08:34上午断网,开始整理

9.按位查找,返回第i个元素(带头结点)

//按位查找,返回第i个元素(带头结点)
LNode*GetElem(LinkList L, int i ){
    if(i<0)
        return NULL;            //输入的值不合法
    LNode *p;                    //指针p当前扫描到的结点
    int j = 0;                    //当前p指向的第几个结点
    p = L;                        //L指向头结点,头结点是第0个结点(不存数据)
    while(p!=NULL && j<i){        //循环找到第i个结点
        p = p->next;
        j++;
    }
    return p;
}

 10.王道书版:按位查找,返回第i个元素(带头结点)

//王道书版:按位查找,返回第i个元素(带头结点)

LNode*GetElem(LinkList L, int i ){
    int j = 1;
    LNode *p = L->next;
    if(i==0)
        return L;                //返回头结点
    if(i<1)
        return NULL;
    while(p!=NULL && j<i){
        p = p->next;
        j++;
    }    
    return p;
}
// 按值查找,找到数据域 ==e 的结点
LNode *LocateElem(LinkList L, ElemType e){
    LNode *p = L->next;
    //从第1个结点开始查找数据域为e的结点
    while (p != NULL && p->data != e)
        p = p->next;
    return p ;                    // 找到后返回该结点指针,否则返回NULL
}
按值查找,找到数据域 ==e 的结点
//求表的长度

int Length(LinkList){
    int len = 0;                // 统计表长
    LNode *p = L;
    while (p->next != null){
        p = o->next;
        len++;
    }
    return len;

}
求表的长度
//双链表的初始化(带头结点)

//初始化双链表
typedef struct DNode{
    ElemType  data;
    struct DNode *prior, *next;
}DNode, *DLinklist;


bool InitDLinkList(DLinkList &L){
    L = (DNode *)malloc(sizeof(DNode));        //分配一个头结点
    if(L==NULL)                                // 内存不足,分配失败
        return false;                        
    L->prior = NULL;                        // 头结点的prior永远指向NULL
    L->next = NULL;                            // 头结点之后暂时还没有结点
    return true;        
}
 
// 判断双链表是否为空(带头结点)
bool Empty(DLinklist L){
    if(L->next == NULL)
        return true;
    else
        return false;
}

viod testDLinkList(){
    //初始化双联链表
    DLinkList L;
    InitDLinkList(L);
    // 后续代码
}
双链表的初始化(带头结点)
// 双链表的后插入操作(按位序插入(就是找到该i-1结点,进行后插),前插操作(找到该结点的前一个结点,进行后插)都是在后插基础上)

// 在p结点之后插入s结点
boo InsertNextDNode(DNode *p, DNode *s){
    if(p==NULL || s==NULL)    //    非法参数
        return false;
    s->next = p ->next;
    if (p->next != NULL)        //如果p结点有后继结点
        p->next->prior = s;
    s->prior = p;
    p->next = s;
    return true;
}
双链表的后插入操作
//双链表的删除
// 删除p结点的后继结点
bool DeleteNextDNode(DNode *p){
    if (P==NULL)    
        return false;
    DNode *p = p->next;            //找到p的后继结点q
    if (q->next!=NULL)
        return false;            // p没有后继
    p->next =q->next;    
    if (q->next!=NULL)            //q结点不是最后一个结点
        q->next->prior = p;        
    free(q);                    // 释放结点空间
    return true;    
}

//销毁一个双链表
void DestoryList(DLinklist &L){
    //循环释放各个数据结点
    while(L->next!=NULL)
        DeleteNextDNode(L);
    free(L);                    //释放头结点
    L = NULL;                    //头指针指向NULL
}
双链表的删除
//双链表的遍历
//后向遍历
while(p!=NULL){
    //对结点p做相应处理,如打印
    p=p->next;
} 

//向前遍历
while(p!=NULL){
    //对结点p做相应处理,如打印
    p=p->prior;
} 

//向前遍历(跳过头结点)
while(p->prior!=NULL){
    //对结点p做相应处理,如打印
    p=p->prior;
} 
双链表的遍历
//循环单链表
typedef struct DNode{
    ElemType  data;
    struct DNode *prior, *next;
}DNode, *DLinklist;

//初始化一个循环单链表
bool InitDLinkList(DLinkList &L){
    L = (DNode *)malloc(sizeof(DNode));        //分配一个头结点
    if(L==NULL)                                // 内存不足,分配失败
        return false;                        
    L->next = L;                            // 头结点next指向头结点
    return true;        
}
// 判断循环单链表是否为空
bool Empty(DLinklist L){
    if(L->next == L)
        return true;
    else
        return false;
}
//判断结点p是否为循环单链表的表未结点
bool isTail(LinkList L, LNode *p){
    if (p->next==L)
        return true;
    else
        return false;
}

viod testDLinkList(){
    //初始化双联链表
    DLinkList L;
    InitDLinkList(L);
    // 后续代码
}
循环单链表
//循环单双链表
typedef struct DNode{
    ElemType  data;
    struct DNode *prior, *next;
}DNode, *DLinklist;

//初始化空的循环双链表
bool InitDLinkList(DLinkList &L){
    L = (DNode *)malloc(sizeof(DNode));        //分配一个头结点
    if(L==NULL)                                // 内存不足,分配失败
        return false;                        
    L->prior = L;                            // 头结点prior指向头结点
    L->next = L;                            // 头结点的next指向头结点
    return true;        
}
// 判断循环双链表是否为空
bool Empty(DLinklist L){
    if(L->next == L)
        return true;
    else
        return false;
}
//判断结点p是否为循环双链表的表尾结点
bool isTail(LinkList L, LNode *p){
    if (p->next==L)
        return true;
    else
        return false;
}

viod testDLinkList(){
    //初始化双联链表
    DLinkList L;
    InitDLinkList(L);
    // 后续代码
}
循环单双链表
// 双链表的插入
//在p结点之后插入s结点
bool InserNextDNode(DNode *p, DNode *s){
    s->next = p->next;                //将结点*s插入到结点*p之后
    p->next->prior = s;
    s->prior = p;
    p->next = s;
}
双链表的插入
// 用代码定义一个静态链表(王道版)
# define MaxSize 10                    //静态链表的最大长度
typedef struct{                        //静态链表结构类型的定义
    ElemType data;                    //存储数据元素
    int next;                        //下一个元素的数组下标
}SLinkList[MaxSize];    

void  testSLinkList(){
    SLinkList a;                    // a是一个静态链表
    // ....后续代码
}

//等价于如下↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//定义一个静态链表
# define MaxSize 10                    //静态链表的最大长度
struct Node{                        //静态链表结构类型的定义
    ElemType data;                    //存储数据元素
    int next;                        //下一个元素的数组下标
};
// 可用SLinkList定义 "一个长度为MaxSize的Node型数组"
typedef  struct Node SLinkList[MaxSize];        //主要是强调我是一个表,不是数组

void  testSLinkList(){
    struct Node a[MaxSize];            // a是一个Node型数组
    // ....后续代码
}
用代码定义一个静态链表

 2020-5-12 21:43:35

不知不觉更了那么多,小有成就感!

//定义一个栈,初始化操作

#define MaxSize 10;                 //定义栈中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         // 静态数组存放栈中元素
    int top;                        // 栈顶指针
} SqStack;

//初始化栈
viod InitStack(SqStack &S){
    S.top = -1 ;                    //初始化栈顶指针
} 

//判断栈空
bool StackEmpty(SqStack S){
    if(S.top=1);                    // 栈空
        return  true;               
    else
        return false;               // 不空
}

void testStack(){
    SqStack S;                      //声明一个顺序栈(分配空间)
    InitStack(S);                  
    //后续操作  增删改查
}
定义一个栈,初始化操作
//进栈操作

#define MaxSize 10;                 //定义栈中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         // 静态数组存放栈中元素
    int top;                        // 栈顶指针
} SqStack;


//新元素入栈
bool Push(SqStack &&S, ElemType x){
    if(S.top==MaxSize-1)            // 栈满,报错
        return false
    S.top = S.top+1                 // 指针先加1
    S.data[S.top] = x;              // 新元素入栈
    //上面两行代码等价于    S.data[++S.top] = x;     ++在前,则是先加,后用
    return  true;
}
进栈操作
// 出栈和读取栈顶元素操作
#define MaxSize 10;                 //定义栈中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         // 静态数组存放栈中元素
    int top;                        // 栈顶指针
} SqStack;

// 出栈
bool Pop(SqStack &S, ElemType &x){
    if(S.top=-1)                   // 栈空,报错
        return false;                
    x = S.data[S.top];              //栈顶元素先出栈
    S.top = S.top -1;               //指针再减1
    //上面两行代码等价于 x = S.data[S.top--];       //先用 后减
    return true;
}

//读取栈顶元素
bool GetTop(SqStack S, ElemType &x){
    if(S.top==1)                    // 栈空,报错
        return false;
    x = S.data[S.top];              // x记录栈顶元素
    return true;                                          
}
出栈和读取栈顶元素操作
// 共享栈
#define MaxSize 10;                 //定义栈中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         // 静态数组存放栈中元素
    int top0;                       // 0号栈栈顶指针
    int top1;                       // 1号栈栈顶指针
} SqStack;

// 初始化栈
void InitStack(ShStack &S){
    S.top0 = -1;                    // 初始化栈顶指针
    S.top1 = MaxSize ;
}

// 栈满的条件   top0 + 1 == top1
共享栈
//顺序队列

#define MaxSize 10                  //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         //用静态数组存放队列元素
    int front , rear;               // 队头指针和对尾指针
}SqQueue;

//初始化队列
void InitQueue(SqQueue &Q){
    //初始时 队列,对尾指针指向0
    Q.rear = Q.front = 0;
}

// 判断队列是否为空
bool QueueEmpty(SqQueue Q){
    if(Q.rear==Q.front)             // 队空条件
        return true;
    else
        return false;
}


void testQueue(){
    // 声明一个队列(顺序存储)
    SqQueue Q;
    InitQueue(Q);
    // 后续操作........
}
顺序队列
//循环队列------- 入队操作
#define MaxSize 10                  //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         //用静态数组存放队列元素
    int front , rear;               // 队头指针和对尾指针
}SqQueue;

//判断队列是否为空
bool QueueEmpty(SqQueue Q){
    if(Q.rear==Q.front)             //队空条件
        return true;
    else
        return false;
}

//入队
bool EnQueue(SqQueue &Q, ElemType x){
    if((Q.rear+1)%MaxSize==Q.front)
        return false;               //队满则报错
    Q.data[Q.rear] = x;             // 新元素插入队尾
    Q.rear = (Q.rear+1)%MaxSize;    //队尾指针加1取模(就是取余操作)
    // 用模运算将存储空间在逻辑上变成了"环状"
    return true;
}
循环队列------- 入队操作
// 循环队列---出队

// 出队(删除一个队头元素,并用x返回)
bool DeQueue(SqQueue &Q, ElemType &x){
    if(Q.rear==Q.front)
        return false;               // 队空则报错
    x = Q.data[Q.front];            
    Q.front = (Q.front+1)%MaxSize;  // 队头指针后移
    return true;
}

// 获得队头元素的值,用x返回
bool GetHead(SqQueue Q, ElemType &x){
    if(Q.rear == Q.front)
        return false;               // 队空则报错
    x = Q.data[Q.front];            
    return true;
}
循环队列---出队
//记住如下内容
# 队列元素个数
(rear+MaxSize-front)%MaxSize

# 以下内容都是: 指向队尾元素的后一个位置(下一个应该是插入位置)
//方案一 : 判断队列已满/已空(浪费空间,其他的2,3方案都不浪费)
#define MaxSize 10                  //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         //用静态数组存放队列元素
    int front , rear;               // 队头指针和对尾指针
    // 初始化时 front  rear 都是为0
}SqQueue;

# 队列已满的条件: 队尾指针的再下一个位置是队头
(Q.rear+1)%MaxSize == Q.front

# 队空条件
Q.rear == Q.front

//方案二 : 判断队列已满/已空
#define MaxSize 10                  //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         //用静态数组存放队列元素
    int front , rear;               // 队头指针和对尾指针
    int size;                       // 队列当前长度
    // 初始化时 front  rear size 都是为0
}SqQueue;

# 插入成功      size++
# 删除成功      size--

# 队满条件      size==MaxSize
#队空条件       size==0


//方案三  : 判断队列已满/已空
#define MaxSize 10                  //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];         //用静态数组存放队列元素
    int front , rear;               // 队头指针和对尾指针
    int tag;                       // 最近进行的是删除/插入
    // 初始化时 front=rear=0  tag=0
}SqQueue;

#每次删除操作成功时,都令tag=0;
#每次插入操作成功时,都令tag=1;
//只有删除操作,才可能导致队空
# 队空条件      front==rear && tag==0
//只有插入操作,才可能导致队满
# 队满条件      front==rear && tag==1
不同方案判断队列已满和已空
//其他出题方法

# 以下都是指向队尾元素(已截图,详情看截图3.5)
其他出题方法

如图

 

 

 

2020-5-12 21:49:23,,明天再看!

 

2020-5-13 18:32:09

2020-5-13 09:41:13(继续干起来)
//队列的连式存储

//初始化(带头结点)
typedef struct LinkNode{
    ElemType data;
    struct LinkNode *next;
}LinkNode;

typedef struct{
    LinkNode *front, *rear;
}LinkQueue;

//初始化(带头结点)
void InitQueue(LinkQueue &Q){
    //初始时 front, rear都指向头结点
    Q.front = Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
    Q.front->next=NULL;
}

//判断队列是否为空
bool IsEmpty(LinkQueue Q){
    if(Q.front=Q.rear)
        return true;
    else
        return false;
}

void testLinkQueue(){
    LinkQueue Q;                    //声明一个队列
    InitQueue(Q);                   // 初始化队列
    //...后续操作.........
}

//################################################
//初始化(不带头结点)

//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q){
    // 初始化 front, rear 都指向NULL
    Q.front = NULL;
    Q.rear = NULL;
}

//判断队列是否为空(不带头结点)
bool IsEmpty(LinkQueue Q){
    if(Q.front==NULL)
        return true;
    else
        return false;
}

//################################################

// 入队(带头结点)
// 新元素入队(带头结点)
void EnQueue(LinkQueue &Q, ElemType x){
    LinkQueue *s = (LinkNode *)malloc(sizeof(LinkNode));
    s->data = x;
    s->next = null;
    Q.rear->next = s;               //新结点插入到rear之后
    Q.rear = s;                     //修改表尾指针
}

// 入队(不带头结点)

//新元素入队(不带头结点)
void EnQueue(LinkQueue &Q, ElemType x){
    LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
    s->data = x;
    s-next = NULL;
    // 不带头结点的队列,第一个元素入队是哦户需要特别处理 
    if(Q.front == NULL){            // 在空队列中插入第一个元素
        Q.front = s;                // 修改队头队尾指针
        Q.rear = s;
    }else{
        Q.rear->next = s;           //新结点插入到rear结点之后
        Q.rear =s;                  // 修改rear指针
    }
}

//################################################
//出队(带头结点)
//队头元素出队(不带头结点)
bool DeQueue(LinkQueue &Q, ElemType &x){
    if(Q.front==Q.rear)
        return false;               // 空队
    LinkNode *p = Q.front->next;
    x = p->data;                    // 用变量x返回队头元素
    Q.front->next = p->next;        // 修改头结点的next指针
    if(Q.rear==p)                   // 此次是最后一个结点出队
        Q.rear = Q.front;           // 修改rear指针
    free(p);                        // 释放结点空间
    return true;        
}

// 出队(不带头结点)
// 队头元素出队(不带头结点)
bool DeQueue(LinkQueue &Q, ElemType &x){
    if(Q.fron==NULL)
        return false;               // 空队
    LinkNode *p = Q.front;          // p指向此次出队的结点
    x = p->data;                    // 用变量x返回队列元素
    Q.front = p->next;              // 修改front 指针
    if(Q.rear==p){                  //  此次是最后一个结点出队
        Q.front =NULL;              // front 指向 NULL
        Q.rear = NULL;              // rear 指向NULL
    }
    free(P);                        // 释放结点空间
    return  true;           
}
// 链式存储一半不会满,除非内存不足!

//################################################
//栈的应用-----匹配括号算法

// 定义一个栈(可采用链栈,但是考试通常数组即可)
# define MaxSize(10)                // 定义栈中元素的最大个数
typedef struct{
    char data[MaxSize];             // 静态数组存放栈中的元素
    int top;                        // 栈顶指针
}SqStack;

// 考试中可直接使用基本操作,建议简要说明接口

//初始化栈
void InitStack(SqStack &S)

//判断栈是否为空
bool StackEmpty(SqStack S)

// 新元素入栈
bool Push(SqStack &S, char x)

//栈顶元素出栈,用x返回
bool Pop|(SqStack &S, char &x)


bool bracketCheck(char str[], int length){
    SqStack S;
    InitStack(S);                   // 初始化一个栈
    for (int i = 0; i<length; i++){
        if (str[i]=='(' || str[i]=='['||str[i]'{'){
            Push(S, str[i]);        // 扫描到左括号,入栈
        }else{
            if(StackEmpty(S))       // 扫描到右括号,且当前栈空
                return false;       // 匹配失败

            char topElem;
            Pop(S, topElem);        // 栈顶元素出栈
            if(str[i]==')' && topElem !='(')
                return  false;
            if(str[i]==']' && topElem !='[')
                return  false;    
            if(str[i]=='}' && topElem !='{')
                return  false;
        }
    }
    return StackEmpty(S);           // 检索全部括号后,栈空说明匹配成功
}

//################################################

// 一维数组的存储结构
ElemType a[10];                     // 定义一个一维数组

// 定义一个二维数组结构
ElemType b[2] [4];                  // 2行4列的二维数组  

2020-5-22 09:42:23

第四章代码

// 是在看英语难受,,看数据结构

//已经截图 明天再写

// 62020-5-20 22:56:15
// 明天早上5点半起来撸代码
// 已经看完第四章  撸代码

// 串的顺序存储

#define MAXLEN 255              // 预定义最大串长为255
typedef struct{
    // 静态数组实现(定长顺序存储)
    char ch[MAXLEN];            // 每个分量存储一个字符
    int length;                 // 串的实际长度
}SString;


typedef struct{
    // 静态数组实现(堆分配存储)
    char *ch;                   // 按串长分配存储区, ch指向穿的基地址
    int   length;               // 串的长度
}HString;   

HString S;
// 用完需要手动free
S.ch = (char *) mallco(MAXLEN * sizeof(char));


//串的连式存储
// 结合链表的知识考虑优缺点
// 存储密度低,每个字符1B,每个指针4B
typedef struct StringNode{
    char ch;                    //  每个节点存1个字符
    struct StringNode * next;
}StringNode, *StringNode;

// 存储密度提高了
typedef struct StringNode{
    char ch[4];                 // 每个节点存多个字符
    struct StringNode * next;
}StringNode, *Stirng ;


// 基本操作实现
// SubString(&Sub,pos,len):求子串
S.ch = "wangdao";
S.length = 7;

//求子串
bool SubString(SString &Sub, SString S, int pos, int len){
    // 子串范围越界
    if (pos+len-1 > S.length)
        return  false;
    for(int i = pos; i<pos+len; i++)
        Sub.ch[i-pos+1] = S.ch[i];
    Sub.length = len;
    return true;
}


// 比较操作  StrCompare(S, T)

// 比较操作. 若S>T, 则返回值>0;若S=T. 则返回值=0; 若S<T, 则返回值<0

int StrCompare(SString S, SString T){
    for(int i=1; i<=S.length && i<=T.length; i++){
        if(S.ch[i]!=T.ch[i])
            return S.ch[i]-T.ch[i];
    }
    // 扫描过的所有字符都相同.则长度长的串更大
    return S.length-T.length;
}


// 定位操作
// Index(S, T) 定位操作
int Index(SString S, SString T){
    int i = 1, n =StrLength(S), m=StrLength(T);
    SString sub;                // 用于暂存子串
    while(i<=n-m+1){
        SubString (sub, S, i, m);
        if(StrCompare(sub, T)!=0)   ++i;
        else return i;          // 返回子串在主串的位置
    }
    return 0;                   // S中不存在与T相等的子串
} 


// 朴素模式匹配算法
int Index(SString S, SString T){
    int k = 1;
    int i = k, j=1;
    while(i<=S.length && j<T.length){
        if(S.ch[j]=T.ch[j]){
            ++i;
            ++j;                // 继续比较后继字符
        }else{
            k++;
            i=k;
            j=1;
        }
    }
    if(j>T.length)
        return k;
    else
        return 0;
}


// 课本中的朴素模式匹配
int Index(SString S, SString T){
    int i = 1, j=1;
    while(i<=S.length && j<T.length){
        if(S.ch[j]=T.ch[j]){
            ++i;
            ++j;                // 继续比较后继字符
        }else{
            i=i-j+2;
            j=1;                // 指针后退重新开始匹配
        }
    }
    if(j>T.length)
        return i-T.length;
    else
        return 0;
}


// KMP算法代码

int Index_KMP(SString S, SString T, int next[]){
    int i = 1, j =1;
    while(i<=S.length & j<=T.length){
        if(j==0|| S.ch[i]==T.ch[j]){
            ++j;
            ++i;                // 继续比较后继字符
        }
        else
            i=next[j];          // 模式串向右移动
    }
    if(j>T.length)
        return i-T.length;      // 匹配成功
    else
        return 0;
}

 

posted @ 2020-05-09 11:15  我想喝杨枝甘露~  阅读(414)  评论(0)    收藏  举报