zoukankan      html  css  js  c++  java
  • 我学《数据结构与算法》 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=2*s;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];
                }
            }
        }
      

    参考资料

  • 相关阅读:
    成熟到优秀的瓶颈问题
    今天我们为什么不成功
    将HTML标签变为小写
    2010世界杯 排阵型 猜比分
    又一款 jQuery 头图切换形式
    整理下工作环境的相应资源
    prototype 的ajax
    即时点选的菜单
    如何禁止一个输入框输入
    基于jQuery的仿FLASH 菜单
  • 原文地址:https://www.cnblogs.com/crazymosquito/p/7082833.html
Copyright © 2011-2022 走看看