数据结构和算法的基本知识点复习

  • 树的不同类型,full tree是所有非叶结点都有左右两个子节点,complete tree是类似于将结点按层序排列起来的树,perfect tree是在full tree的基础上每一层的结点都填满。AVL树是一种特殊的BST,其特点是对于每一个结点,其左子树的高度和右子树最多相差为1。关于ALV保持如何保持平衡的问题,根据情况氛围single rotation或是double rotation,细节见(http://www.cs.washington.edu/education/courses/cse373/12wi/lectures/cse373-12wi-lec07-AVLTrees-day2.html)
  • 最小二叉堆,任意非根节点的值都比父节点大,这种性质是其insert和delete的时间复杂度都是log(n),因此常常用来保存前K大的数。由于二叉堆相当于是complete tree的结构,实现都是使用数组并通过下标访问父节点/左右子节点。设数组为A[n](一般下标从1算起,A[0]存二叉堆的size), 对于findMin操作,直接返回A[1] (根节点);对于insert操作,设当前结点总数为K, 那么新结点的位置初始为K+1,然后不断比较下标除二的值,不断交换知道新值大于其父节点值,因此复杂度为log(n);对于delete操作,把最末结点当成根节点,(相当于删除了根节点),然后依次比较其左右子节点的值,然后不断交换向下直到稳定。
  • hash table,常数复杂度的存取。设计哈希函数的时候需要避免键值冲突,尽量平均分配映射值。解决hash值冲突的主要办法有两个:seperate chaining和open addressing. Seperate chaining是对每一个hash值都保存一个链表,这样取的速度的会略慢(因为要遍历链表)。Open addressing的方法是一旦键值冲突,使用probe函数计算下一个存储位置,但是一旦table的load factor大于1/2,open address的performance会显著下降,但是open address的好处是不需要额外的空间保存链表,但是存取速度相对比较弱,在load factor较大的时候需要扩充hash table的size。
  • 排序,比较重要的有插入排序,选择排序,堆排序,归并排序,快速排序。
    View Code
    //insertion sort, for Kth element, make sure the first K elements are sorted
    void insertion_sort(int[] A, int n) {
        if (!n) return;
        for(int i = 1; i < n; ++i) {
            for(int j = i; j >= 0; --j) {
                if (A[j] > A[j-1]) break;
                else {
                    int tmp = A[j-1];
                    A[j-1] = A[j];
                    A[j] = tmp;
                }
            }
        }
    }
    
    //selection sort, for Kth element, find the smallest element in the rest
    void selection_sort(int[] A, int n) {
        if (!n) return;
        for(int i = 0; i < n; ++i) {
            int max = i;
            for(int j = i+1; j <= n; ++j) {
                if (A[j] > A[max]) max = j;
            }
            int tmp = A[i];
            A[i] = A[max];
            A[max] = tmp;
        }
    }
    
    //heap sort, treat the array as a heap and sort it
    void heap_sort(int[] A, int n) {
        for(int i = 0; i < n; ++i) {
            int min = deleteMin(A, i, n); //operation defined in minBinary heap
            A[i] = min;
        }
    }
    
    //merge sort, divide and conquer
    void merge_sort(int[] A, int n); 
    
    //quick sort
    void quick_sort(int[] A, int start, int end) {
        if (start >= end) return;
        if (start + 1 == end) {
            A[start] = min(A[start], A[end]);
            A[end] = max(A[start], A[end]);
            return;
        }
        int mid = start + ((end-start) >> 1);
        int pivot = A[mid];
        int i = start;
        int j = end;
        while (i <= j) {
            while (A[i] < pivot) ++i;
            while (A[j] > pivot) --j;
            if (i <= j) { 
                swap(A[i], A[j]);
                ++i;
                --j;
            }
        }
        if (start < j) quick_sort(A, start, j);
        if (i < end) quick_sort(A, i, end);
    }

     

posted on 2013-02-12 00:53  梁霄  阅读(420)  评论(0)    收藏  举报

导航