我学《数据结构与算法》 20155314刘子健

我学《数据结构与算法》

我眼中的数据结构

一句话

组织数据的方式

分类

  • 逻辑结构
    • 线性结构(一对一)
    • 非线性结构
      • 集合(无逻辑关系)
      • 树(一对多)
      • 图(网)(多对多)
  • 存储结构物理结构
    • 顺序
    • 链式
    • 散列
    • 索引

整合起来看就是

基本操作

我学过的算法

  • 排序
    • 基于关键字比较
      • 插入排序
      • 快速排序
      • 堆排序
      • 归并排序
    • 不基于关键字比较
      • 计数排序
      • 基数排序
  • 查找
    • 静态
      • 折半查找
    • 动态
      • 散列查找
      • 基于二叉搜索树的查找
  • 遍历
    • 二叉树的遍历
      • 先序遍历
      • 中序遍历
      • 后序遍历
    • 图的遍历
      • 深度优先
      • 广度优先
    • 拓扑排序
  • 优化
    • 按问题组织算法
      • 最优二叉树——Huffman算法
      • 最小生成树
        • Prim算法
        • Kruskal算法
      • 最短路径
        • Dijkstra算法
        • Floyd算法
      • 关键路径
    • 按策略组织算法
      • 贪心算法
      • 动态规划
  • 字符串匹配——KMP算法
  • 经典问题
    • 背包问题
      • 0-1背包问题——动态规划
      • 分数背包问题——贪心策略
    • N皇后问题——回溯法
    • 旅行商问题——动态规划
    • 子集和问题
      • 回溯法
      • 动态规划——转化为0-1背包问题

整合起来看就是

C语言实现

数据结构(存储结构)

  • 线性表
    • 顺序表

      define LIST_INIT_SIZE 80 //线性表存储空间的初始分配量

      define LISTINCREMENT 10 //线性表存储空间的分配增量

      typedef int ElemType;
      typedef struct {
      ElemType *elem; //存储空间基址
      int length; //当前长度
      int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
      }SqList; //顺序表

    • 单链表

      typedef int ElemType;
      typedef struct LNode {
      ElemType data; //数据域
      struct LNode next; //指针域
      }LNode,
      LinkList;
      LinkList L; //L为单链表的头指针

  • 栈(先进后出)
    • 顺序栈

      define STACK_INIT_SIZE 100 //最大栈长度

      typedef int ElemType;
      typedef struct {
      ElemType *base; //栈底指针
      ElemType *top; //栈顶指针
      int stacksize;
      }SqStack;

    • 链栈

      define STACK_INIT_SIZE 100

      typedef int ElemType;
      typedef struct Node {
      ElemType data;
      struct Node next;
      }
      LinkStack;

  • 队列(先进先出)
    • 循环队列

      define MAXQSIZE 100 //最大队列长度

      typedef int ElemType;
      typedef struct {
      ElemType *base; //动态分配存储空间
      int front; //头指针,若队列不空,指向队列头元素
      int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
      int queuesize;
      }SqQueue;

    • 链队列

      typedef int QElemType;
      typedef struct QNode { //结点类型
      QElemType data;
      struct QNode next;
      }QNode,
      QueuePtr;
      typedef struct { //链队列类型
      QueuePtr front; //队头指针
      QueuePtr rear; //队尾指针
      }LinkQueue;

    • 二叉链表

      typedef int ElemType;
      typedef struct BiTNode { //结点结构
      ElemType data;
      struct BiTNode lchild,rchild; //左右孩子指针
      }BiTNode,*BiTree;
      BiTree T; //二叉链表的根指针

    • B树

      define m 3 // B树的阶,此设为4

      typedef int KeyType;
      typedef struct {
      KeyType key;
      char data;
      }Record;
      typedef struct BTNode {
      int keynum; //结点中关键字个数,结点大小
      struct BTNode *parent; //指向双亲结点的指针
      KeyType key[m+1]; //关键字向量(0号单元不用)
      struct BTNode *ptr[m+1]; //子树指针向量
      Record recptr[m+1]; //记录指针向量(0号单元不用)
      }BTNode,
      BTree; //B树结点和B树的类型
      typedef struct {
      BTNode *pt; //指向找到的结点的指针
      int i; //1..m,在结点中的关键字序号
      int tag; //标志查找成功(=1)或失败(=0)
      } Result; //在B树的查找结果类型

    • 邻接矩阵

      define MAX_VERTEX_NUM 100

      typedef char VertexType;
      typedef int EdgeType;
      typedef enum
      {
      DG,UDG
      }GraphKind;
      typedef struct { //图的定义
      VertexType vexs[MAX_VERTEX_NUM]; //存储顶点信息
      EdgeType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵,存储边的信息
      int vexnum,arcnum; //顶点数,边数
      GraphKind kind; //图的种类标志
      }MGraph;

    • 邻接表

      define MAX_VERTEX_NUM 100

      typedef char VertexType;
      typedef enum
      {
      DG,UDG
      }GraphKind;
      typedef struct ArcNode { //边的结点结构
      int adjvex; //该边所指向的顶点的位置
      struct ArcNode *nextarc; //指向下一条边的指针
      }ArcNode;
      typedef struct VNode { //顶点的顶点结构
      VertexType data; //顶点信息
      ArcNode *firstarc; //指向第一条依附于该顶点的边
      }VNode,AdjList[MAX_VERTEX_NUM];
      typedef struct { //图的定义
      AdjList vertices;
      int vexnum,arcnum; //顶点数,边数
      GraphKind kind; //图的种类标志
      }ALGraph;

算法

  • 排序算法

    include <stdio.h>

    include <stdlib.h>

    define N 5

    void BubbleSort(int a[]);
    void SelectionSort(int a[]);
    void InsertionSort(int a[]);
    void QSort(int a[],int s,int t);
    int Partition(int R[],int low,int high);
    void CountingSort(int a[],int k);
    int max(int a[]);
    void HeapSort(int a[]);
    void MaxHeapify(int a[],int s,int m);
    void BuildMaxHeap(int a[]);
    void MergeSort(int a[],int s,int t);
    void Merge(int a[],int i,int m,int n);
    void main()
    {
    int i,j,temp;
    int a[N],b[N];
    printf("请输入%d个整数:",N);
    for(i=0;i<N;i++)
    {
    scanf("%d",&a[i]);
    }
    BubbleSort(a); //冒泡排序
    /for(i=0;i<N;i++) //冒泡排序
    {
    for(j=0;j<N;j++)
    {
    if(a[j]>a[j+1])
    {
    temp=a[j];
    a[j]=a[j+1];
    a[j+1]=temp;
    }
    }
    }
    ///冒泡排序
    SelectionSort(a);
    //InsertionSort(a); //插入排序
    /for(i=0,j=1;i<N,j<N+1;i++,j++) //将下标改为从1开始
    {
    b[j]=a[i];
    }
    QSort(b,1,N);
    for(i=1;i<N+1;i++)
    {
    printf("%d ",b[i]);
    }
    / //快速排序
    //CountingSort(a,max(a)); //计数排序
    //HeapSort(a); //堆排序
    /for(i=0,j=1;i<N,j<N+1;i++,j++) //将下标改为从1开始
    {
    b[j]=a[i];
    }
    MergeSort(b,1,N);
    for(i=1,j=0;i<N+1,j<N;i++,j++) //将数组下标还原为从0开始
    {
    a[j]=b[i];
    }
    / //归并排序
    for(i=0;i<N;i++)
    {
    printf("%d ",a[i]);
    }
    }

    void BubbleSort(int a[]) //冒泡排序
    {
    int i,j,temp;
    for(i=0;i<N-1;i++)
    {
    for(j=i+1;j<N;j++)
    {
    if(a[i]>a[j])
    {
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
    }
    }
    }
    }

    void SelectionSort(int a[]) //选择排序
    {
    int i,j,k,temp;
    for(i=0;i<N-1;i++)
    {
    k=i; //从下标为0处开始记录
    for(j=i+1;j<N;j++)
    {
    if(a[j]<a[k])
    {
    k=j; //记录最小数下标位置
    }
    }
    if(k!=i) //优化处理:若最小数所在的下标位置不在下标位置i,则交换
    {
    temp=a[k];
    a[k]=a[i];
    a[i]=temp;
    }
    }
    }

    void InsertionSort(int a[]) //插入排序
    {
    int i,j,b[N];
    for(i=0,j=1;i<N,j<N+1;i++,j++) //将下标改为从1开始,便于设置监视哨a[0]
    {
    b[j]=a[i];
    }
    for(i=2;i<=N;i++)
    {
    if(b[i]<b[i-1])
    {
    b[0]=b[i]; //复制为监视哨
    for(j=i-1;b[0]<b[j];j--)
    {
    b[j+1]=b[j];
    }
    b[j+1]=b[0];
    }
    }
    for(i=1,j=0;i<N+1,j<N;i++,j++) //将数组下标还原为从0开始
    {
    a[j]=b[i];
    }
    }

    void QSort(int a[],int s,int t) //快速排序
    {
    int pivotloc;
    if(s<t-1) //长度大于1
    {
    pivotloc=Partition(a,s,t); //对a[]进行一次划分
    QSort(a,s,pivotloc-1); //对左子序列递归排序,pivotloc是轴位置
    QSort(a,pivotloc+1,t); //对右子序列递归排序
    }

    }
    int Partition(int R[],int low,int high)
    {
    int pivotkey;
    R[0]=R[low];
    pivotkey=R[low]; //"轴"
    while (low<high)
    {
    while (low<high&&R[high]>=pivotkey)
    high--;
    R[low]=R[high];
    while (low<high&&R[low]<=pivotkey)
    ++low;
    R[high]=R[low];
    }
    R[low]=R[0];
    return low;
    }

    void CountingSort(int a[],int k) //计数排序
    {
    int i,j;
    int C[N]; //引入索引数组C
    int R[N]; //新建存储数组R
    for(i=0;i<=k;i++)
    {
    C[i]=0; //初始化数组c
    }
    for(i=0;i<N;i++)
    {
    C[a[i]]++; //c[i]中存值等于i的元素个数
    }
    for(i=1;i<=k;i++)
    {
    C[i]=C[i]+C[i-1]; //c[i]中存值小于等于i的元素个数
    }
    for(j=N-1;j>=0;j--)
    {
    R[C[a[j]]]=a[j];
    C[a[j]]--; //下一个值为a[j]的元素被放到a[j]的前一个位置
    }
    for(i=0;i<N;i++)
    {
    a[i]=R[i+1];
    }
    }
    int max(int a[])
    {
    int i;
    int max;
    max = a[0];
    for(i=1;i<N;i++)
    {
    if (max<a[i])
    max=a[i];
    }
    return max;
    }

    void HeapSort(int a[]) //堆排序
    {
    int temp,i;
    BuildMaxHeap(a); //建大顶堆
    for(i=N;i>1;i--)
    {
    temp=a[0]; //将堆顶元素和当前未经排序子序列a[0...i-1]中最后一个元素交换
    a[0]=a[i-1];
    a[i-1]=temp;
    MaxHeapify(a,0,i-2); //调整a[0...i-2]使其成为大顶堆
    }
    }
    void MaxHeapify(int a[],int s,int m) //维护堆的性质
    {
    int rc,j;
    rc=a[s]; //暂存a[s]
    for(j=2s;j<=m;j=2)
    {
    if(j<m&&a[j]<a[j+1]) j++; //左右"孩子"之间先进行相互比较,令j指示较大的关键字所在位置
    if(rc>=a[j]) break; //再作"根"和"孩子"之间比较,若">="成立,则说明已找到rc的插入位置s,不需继续向下调整
    a[s]=a[j];
    s=j; //否则关键字上移,仍需继续向下调整
    }
    a[s]=rc; //将调整前的堆顶插入到s位置
    }
    void BuildMaxHeap(int a[]) //建堆
    {
    int i;
    for(i=N/2-1;i>=0;i--)
    {
    MaxHeapify(a,i,N); //建大顶堆
    }
    }

    void MergeSort(int a[],int s,int t) //归并排序
    {
    int m;
    if(s<t)
    {
    m=(s+t)/2; //分解
    MergeSort(a,s,m); //解决
    MergeSort(a,m+1,t);
    Merge(a,s,m,t); //合并
    }
    }
    void Merge(int a[],int i,int m,int n) //归并有序序列a[i...m]和a[m+1...n]
    {
    int j,k,p,q;
    int R[N];
    for(j=i;j<=n;j++)
    {
    R[j]=a[j]; //复制
    }
    for(j=m+1,k=i;i<=m&&j<=n;k++)
    {
    if(R[i]<=R[j]) a[k]=R[i++];
    else a[k]=R[j++];
    }
    if(i<=m)
    {
    for(p=i,q=k;p<=m,q<=n;p++,q++)
    {
    a[q]=R[p];
    }
    }
    if(j<=n)
    {
    for(p=j,q=k;p<=n,q<=n;p++,q++)
    {
    a[q]=R[p];
    }
    }
    }

参考资料

posted @ 2017-06-26 22:40  20155314刘子健  阅读(275)  评论(0)    收藏  举报
Live2D