数据结构之一对一(完结)

个人介绍及问题解决
系统按照最大数据类型对齐;

为什么同一结构,在不同平台大小不同?
因为:

  • 不同平台上相同类型所占(内存)字节不同
  • 不同平台对齐方式不一样

#pragma pack(1):系统按照一个字节对齐。

1

struct Node
{
int a;
short b;
char c;
short d;
}

小端存储:低字节写在低地址里
联合体内所有变量共用同一块地址空间
全局变量和静态变量默认初始化为0

数据结构有几种结构?
集合,一对一,一对多,多对多。四种!

OneByOne(一对一)

---------------------------------------------------------------------------------------------
元素同属一个集合,前后元素有关系并单向

例如:线性表:
一个表里面元素a1到aN,a1没有直接前驱有且仅有一个直接后继,ai作为中间元素,有且仅有一个直接前驱
和一个直接后继,aN作为表的尾元素,没有直接后继,有且仅有一个直接前驱

直接前驱也叫直接前件

线性表的两种储存结构

  • 顺序储存→数组
  • 链式储存→链表

递归和循环的优缺点
递归:代码简单,逻辑简单(便于阅读),但是函数跳转浪费时间,函数参数占用空间
循环:相对于递归,节约资源,但是每层循环逻辑必须弄清

stack(栈)

特性:先进后出,且只能操作栈顶
本质:也许是数组,也许是链表


stack

常用栈:单向链表,头添加,头删除

八个基本操作

  • Push 添加元素
  • Pop 删除元素
  • Init 初始化栈
  • Clear 清空栈
  • Deatroy 销毁栈
  • GetCount 获得栈元素个数
  • GetTop 得到栈顶
  • IsEmpty 判断是否是空栈
#include<stdio.h>
#include<stdlib.h>

typedef struct node1
{
    int nValue;
    struct node1 *pNext;
}MyStack;

typedef struct node2
{
    MyStack *pTop;
    int nCount;
}Stack;

//初始化
void s_Init(Stack **pStack)
{
    if(pStack == NULL)return;
    *pStack = (Stack*)malloc(sizeof(Stack));
    (*pStack)->pTop = NULL;
    (*pStack)->nCount = 0;
}

//压栈
void s_Push(Stack *pStack,int nNum)
{
    MyStack *pTemp = NULL;

    if(pStack == NULL)
    {
        printf("栈没啦!!!\n");
        return;
    }

    //开辟新节点装载值
    pTemp = (MyStack*)malloc(sizeof(MyStack));
    pTemp->nValue = nNum;
    pTemp->pNext = pStack->pTop;

    pStack->pTop = pTemp;
    pStack->nCount++;
}

//出栈
int s_Pop(Stack *pStack)
{
    MyStack *pDel = NULL;
    int nNum;
    if(pStack == NULL || pStack->pTop == NULL)return -1;

    pDel = pStack->pTop;
    nNum = pDel->nValue;

    pStack->pTop = pStack->pTop->pNext;
    free(pDel);
    pDel = NULL;
    pStack->nCount--;
    return nNum;
}

//清空
void s_Clear(Stack *pStack)
{
    if(pStack == NULL || pStack->pTop == NULL)return;

    while(pStack->nCount)
    {
        s_Pop(pStack);
    }
}

//销毁
void s_Destroy(Stack **pStack)
{
    s_Clear(*pStack);
    free(*pStack);
    *pStack = NULL;
}

//获得栈内元素个数
int s_GetCount(Stack *pStack)
{
    if(pStack == NULL)return -1;

    return  pStack->nCount;
}

//获得栈顶
MyStack *s_GetTop(Stack *pStack)
{
    if(pStack == NULL)return NULL;
    return pStack->pTop;
}

//是否为空栈
int s_IsEmpty(Stack *pStack)
{
    if(pStack == NULL)return -1;

    return (pStack->nCount)?0:1;
}

int main()
{
    Stack *pStack = NULL;
    s_Init(&pStack);

    s_Push(pStack,1);
    s_Push(pStack,2);
    s_Push(pStack,3);
    s_Push(pStack,4);
    s_Push(pStack,5);

    printf("%d\n",s_Pop(pStack));
    printf("%d\n",s_Pop(pStack));

    printf("-------------------------------------------------\n");
    printf("%d\n",s_GetCount(pStack));

    s_Destroy(&pStack);
    s_Push(pStack,5);
    return 0;
}

二级指针的使用:一般是参数无中生有,和从有到无

递归相当于栈的实际应用
因为:解决大问题的方式与其子问题方式一致(定义)

斐波那契数列FIBONACCI

也叫黄金分割数列

#include<stdio.h.>
#include<stdlib.h>
int Fibonacci_1(int n)//迭代法
{
    if (n<=2)
    {
        return 1;
    }
    return Fibonacci_1(n-1)+Fibonacci_1(n-2);
}
int Fibonacci_2(int n)
{

    int i = 3;
    int a = 1;
    int b = 1;
    int c = 0;
    if (n<=2)
    {
        return 1;
    }
    for ( ;i <=n; i++)
    {
        c = a+b;
        a = b;
        b = c;
    }

    return c;
}
int main()
{
    printf("%d\n",Fibonacci_1(10));
    printf("%d\n",Fibonacci_2(10));
    return 0;
}

四则运算

后缀表达式(逆波兰表示法)。
中缀表示法:例如:19+41*5-7/6,也叫表达式

转换规则

中缀转后缀(官方版)

借助辅助栈,遇到数字或字符直接打印,遇到符号(+ - * /),拿当前符号与栈顶元素进行优先级比较。如果当前元素优先级高直接入栈,如果当前元素优先级低,则直接出栈直到比当前元素优先级比它低的,如果遇到左括号无条件入栈,如果遇到右括号,将栈内元素依次出栈直到左括号停下来,如果没有元素,就将栈内元素全部拿出。

非官方版

所以运算加括号,将运算符放到括号后面。

后缀转中缀

遇到数字或字符直接进栈,遇到符号将栈顶元素下一个和栈顶元素构成表达式。

Queue

实际应用:打印机
特性:先进先出

queue

#include<stdio.h>
#include<stdlib.h>

typedef struct node3
{
    int nValue;
    struct node3 *pNext;
}MyQueue;

typedef struct node4
{
    int nCount;
    MyQueue* pHead;
    MyQueue *pTail;
}Queue;

void q_Init(Queue **pQueue)
{
    if(pQueue == NULL)return;
    *pQueue = (Queue*)malloc(sizeof(Queue));
    (*pQueue)->nCount = 0;
    (*pQueue)->pHead = NULL;
    (*pQueue)->pTail = NULL;
}

void q_Push(Queue *pQueue,int nNum)
{
    MyQueue *pTemp = NULL;
    if(pQueue == NULL)return;

    pTemp = (MyQueue*)malloc(sizeof(MyQueue));
    pTemp->nValue = nNum;
    pTemp->pNext = NULL;

    if(pQueue->pHead == NULL)
    {
        pQueue->pHead = pTemp;
    }
    else
    {
        pQueue->pTail->pNext = pTemp;
    }

    pQueue->pTail = pTemp;
    pQueue->nCount++;

}
int q_Pop(Queue *pQueue)
{
    MyQueue *pDel = NULL;
    int nNum;
    if(pQueue == NULL || pQueue->pHead == NULL)return -1;

    pDel = pQueue->pHead;
    nNum = pDel->nValue;

    pQueue->pHead = pQueue->pHead->pNext;
    free(pDel);
    pDel = NULL;
    pQueue->nCount--;

    if(pQueue->nCount == 0)
    {
        pQueue->pTail = NULL;
    }

    return nNum;
}

int q_IsEmpty(Queue *pQueue)
{
    if(pQueue == NULL )return -1;
    return pQueue->nCount ? 0:1;
}


Queue To Stack

用两个Queue(队列)实现Stack(栈)

#include<stdio.h>
#include<stdlib.h>

typedef struct node3
{
    int nValue;
    struct node3 *pNext;
}MyQueue;

typedef struct node4
{
    int nCount;
    MyQueue* pHead;
    MyQueue *pTail;
}Queue;

typedef struct node
{
    Queue *pQueue1;
    Queue *pQueue2;
    int nCount;
}Stack;


void q_Init(Queue **pQueue)
{
    if(pQueue == NULL)return;
    *pQueue = (Queue*)malloc(sizeof(Queue));
    (*pQueue)->nCount = 0;
    (*pQueue)->pHead = NULL;
    (*pQueue)->pTail = NULL;
}

void q_Push(Queue *pQueue,int nNum)
{
    MyQueue *pTemp = NULL;
    if(pQueue == NULL)return;

    pTemp = (MyQueue*)malloc(sizeof(MyQueue));
    pTemp->nValue = nNum;
    pTemp->pNext = NULL;

    if(pQueue->pHead == NULL)
    {
        pQueue->pHead = pTemp;
    }
    else
    {
        pQueue->pTail->pNext = pTemp;
    }

    pQueue->pTail = pTemp;
    pQueue->nCount++;

}

int q_Pop(Queue *pQueue)
{
    MyQueue *pDel = NULL;
    int nNum;
    if(pQueue == NULL || pQueue->pHead == NULL)return -1;

    pDel = pQueue->pHead;
    nNum = pDel->nValue;

    pQueue->pHead = pQueue->pHead->pNext;
    free(pDel);
    pDel = NULL;
    pQueue->nCount--;

    if(pQueue->nCount == 0)
    {
        pQueue->pTail = NULL;
    }

    return nNum;
}

int q_IsEmpty(Queue *pQueue)
{
    if(pQueue == NULL )return -1;
    return pQueue->nCount ? 0:1;
}

void s_Init(Stack **pStack)
{
    if(pStack == NULL)return;
    *pStack = (Stack*)malloc(sizeof(Stack));
    (*pStack)->nCount = 0;
    (*pStack)->pQueue1 = NULL;
    (*pStack)->pQueue2 = NULL;

    //初始化两个队列
    q_Init(&((*pStack)->pQueue1));
    q_Init(&((*pStack)->pQueue2));
}

void s_Push(Stack *pStack,int nNum)
{
    MyQueue *pTemp = NULL;
    if(pStack == NULL || pStack->pQueue1 == NULL || pStack->pQueue2 == NULL)return;
    
    //将数值放入非空队列
    if(!q_IsEmpty(pStack->pQueue1))
    {
        q_Push(pStack->pQueue1,nNum);
    }
    else
    {
        q_Push(pStack->pQueue2,nNum);
    }
}


int s_Pop(Stack *pStack)
{
    int nNum;
    if(pStack == NULL || (pStack->pQueue1 == NULL && pStack->pQueue2 == NULL))return -1;

    //检测非空队列
    if(!q_IsEmpty(pStack->pQueue1))
    {
        //将队列元素依次放入空队列里 直到剩一个的时候停下来
        while(pStack->pQueue1->nCount != 1)
        {
            q_Push(pStack->pQueue2, q_Pop(pStack->pQueue1) );
        }
        nNum = q_Pop(pStack->pQueue1);
    }
    else
    {
        //将队列元素依次放入空队列里 直到剩一个的时候停下来
        while(pStack->pQueue2->nCount != 1)
        {
            q_Push(pStack->pQueue1, q_Pop(pStack->pQueue2) );
        }
        nNum = q_Pop(pStack->pQueue2);
    }
    return nNum;
}

Stack To Queue

用两个栈实现队列

#include<stdio.h>
#include<stdlib.h>
typedef struct node1
{
    int nValue;
    struct node1 *pNext;
}MyStack;

typedef struct node2
{
    MyStack *pTop;
    int nCount;
}Stack;
typedef struct node3
{
    Stack *Mystack_1;
    Stack *Mystack_2;
    int nCount;
}MyQueue;

//初始化
void s_Init(Stack **pStack)
{
    if(pStack == NULL)return;
    *pStack = (Stack*)malloc(sizeof(Stack));
    (*pStack)->pTop = NULL;
    (*pStack)->nCount = 0;
}

//压栈
void s_Push(Stack *pStack,int nNum)
{
    MyStack *pTemp = NULL;

    if(pStack == NULL)
    {
        printf("栈没啦!!!\n");
        return;
    }

    //开辟新节点装载值
    pTemp = (MyStack*)malloc(sizeof(MyStack));
    pTemp->nValue = nNum;
    pTemp->pNext = pStack->pTop;

    pStack->pTop = pTemp;
    pStack->nCount++;
}

//出栈
int s_Pop(Stack *pStack)
{
    MyStack *pDel = NULL;
    int nNum;
    if(pStack == NULL || pStack->pTop == NULL)return -1;

    pDel = pStack->pTop;
    nNum = pDel->nValue;

    pStack->pTop = pStack->pTop->pNext;
    free(pDel);
    pDel = NULL;
    pStack->nCount--;
    return nNum;
}   
//是否为空栈
int s_IsEmpty(Stack *pStack)
{
    if(pStack == NULL)return -1;

    return (pStack->nCount)?0:1;
}
void q_Init(MyQueue **queue)
{
    if (queue == NULL )return;
    (*queue) = (MyQueue*)malloc(sizeof(MyQueue));
    (*queue)->Mystack_1 = NULL;
    (*queue)->Mystack_2 = NULL;
    s_Init(&(*queue)->Mystack_2);
    s_Init(&(*queue)->Mystack_1);
    (*queue)->nCount = 0;
}
void q_Push(MyQueue *queue,int nValue)
{
    s_Push(queue->Mystack_2,nValue);
    return;

}
int q_Pop(MyQueue *queue)
{

    int num;
    if (s_IsEmpty((queue)->Mystack_1))
    {
        while (queue->Mystack_2->nCount != 1)
        {
            s_Push((queue)->Mystack_1,s_Pop((queue)->Mystack_2));
        }
        num = s_Pop((queue)->Mystack_2);
        while (queue->Mystack_1->nCount != 0)
        {
            s_Push((queue)->Mystack_2,s_Pop((queue)->Mystack_1));
        }
    }

    return num;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容