zoukankan      html  css  js  c++  java
  • 基础算法总结

    #include <iostream>
    using namespace std;
    
    //-----------LinkedList API-------------
    typedef struct ListNode {
        int key;
        struct ListNode * next;
        struct ListNode * prev;
    }ListNode;
    
    #define LISTSIZE 1000
    ListNode ListNodePool[LISTSIZE];
    int NodeNum = 0;
    
    ListNode NIL;
    
    ListNode * getNewNode(){
        return & ListNodePool[NodeNum++];
    }
    
    void listInit(){
        NIL.next = &NIL;
        NIL.prev = &NIL;
        NIL.key = 0;
    }
    
    void listInsertAtFront(ListNode * node){
        node->next = NIL.next;
        node->prev = &NIL;
        NIL.next->prev = node;
        NIL.next = node;
    }
    
    void listInsertAfter
    (ListNode * dstNode, ListNode * NewNode){
        NewNode->next = dstNode->next;
        NewNode->prev = dstNode;
        dstNode->next->prev = NewNode;
        dstNode->next = NewNode;
    }
    
    void listDelete(ListNode * node){
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    ListNode * listSearch(int k){
        ListNode * x = NIL.next;
        while(x != &NIL && x->key != k){
            x = x->next; }
        return x;
    }
    
    //end of LinkedList API
    
    int data[LISTSIZE];
    
    void insertSort(int data[], int N){
        for(int i = 1; i < N; i++){
        int key = data[i];
        int j;
        for(j = i - 1; j >= 0; j--){
        if(data[j] > key){
        data[j + 1] = data[j];
        }else{
            break;
        }
        }
        data[j + 1] = key;
        }
    }
    
    void showData(int N){
        for(int i = 0; i < N; i++){
        cout << data[i] << " ";
        }
        cout << endl;
    }
    
    void showList(){
        ListNode * curNode = NIL.next;
        while(curNode != & NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
        }
        cout << endl;
    }
    
    void listInsertSort(){
    
    ListNode * curNode = NIL.next->next;
    ListNode * tmpNode;
    while(curNode != &NIL){
        //cout << curNode->key << " " << endl;
        ListNode * dstNode = NIL.next;
    while(dstNode != curNode && dstNode->key < curNodekey){
        dstNode = dstNode->next;
    }
    
        dstNode = dstNode->prev;
        tmpNode = curNode->next;
        listDelete(curNode);
        listInsertAfter(dstNode, curNode);
    curNode = tmpNode;
        }
    }
    
    
    void main(){
        freopen("input.txt", "r", stdin);
        int N;
        cin >> N;
    
        for(int i = 0; i < N; i++){
            cin >> data[i];
            cout << data[i] << " " ;
        }
        cout << endl;
    
        listInit();
        ListNode * dstNode = &NIL;
        for(int i = 0; i < N; i++){
        ListNode * node = getNewNode();
        node->key = data[i];
    listInsertAfter(dstNode, node);
        dstNode = dstNode->next;
        }
    
        ListNode * curNode = NIL.next;
        while(curNode != &NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
        }
        cout << endl;
    
        insertSort(data, N);
        showData(N);
    
        listInsertSort();
        showList();
    }
    
    //--------STACK API--------
    #define STACK_SIZE 100000  //根据需要更改
    typedef struct Element{
        int x;
        int y;
    }Element;
    
    Element Stack[STACK_SIZE];
    int top = 0;
    
    void stackInit(){     top = 0;      }
    
    bool isEmpty(){    return top;  }
    
    Element pop(){    return Stack[top--]; }
    
    void push(Element e){  Stack[top++] = e; }
    
    Element getTop(){    return Stack[top];  }
    //end of stack API
    
    //------------QUEUE API-------------
    #define QUEUE_SIZE 100000
    Element Queue[STACK_SIZE];
    int front = 0;
    int rear = 0;
    
    void queueInit(){    front = rear = 0;  }
    
    bool isEmpty(){      return front==rear;  }
    
    void enQueue(Element e){ Queue[rear++] = e; }
    
    Element deQueue(){ return Queue[front++];  }
    
    Element getFront(){  return Queue[front];    }
    
    
    //Heap API
    #include <iostream>
    using namespace std;
    
    //根据需求调整大小
    #define SIZE 1001
    int heap[SIZE];
    
    #define swap(x, y) {x = x + y; y = x - y; x = x - y;}
    
    void fixDown(int heap[], int pos, int size){
        
    int x = pos;
    if(x > size) return;//exit
        
    // 选出最大的
    int l = 2 * x;
    int r = l + 1;
    int maxPos = x;
    if(l <= size && heap[maxPos] < heap[l]) 
    maxPos = l;
    if(r <= size && heap[maxPos] < heap[r]) 
    maxPos = r;
    
    
    if(maxPos != x){ 
    //如果父节点不是最大的, 进行互换, 并在新的点上继续fixDown
        swap(heap[x], heap[maxPos]);
        fixDown(heap, maxPos, size);
        }
    }
    
    void fixUp(int heap[], int size, int pos){
    int x = pos;
    int p;
    while(x > 1){
        p = x/2;
        if(heap[x] > heap[p]){
        swap(heap[x], heap[p]);
            x = p;
            }else return;
        }
    }
    
    void buildHeap(int heap[], int size){
    for(int i = size/2; i >= 1; i--){
    fixDown(heap, i, size);
        }
    }
    
    //heapSort前要先build heap
    void heapSort(int heap[], int size){
    int oriSize = size;
    for(int i = 0; i < oriSize - 1; i++){ 
    //注意不要把oriSize和size混在一起
    //互换堆顶和最后一个元素,将堆顶元素放在数组最后面
    swap(heap[size], heap[1]);
    size--;
    fixDown(heap, 1, size);
        }
    }
    
    int main(){
    int size = 7;
    for(int i = 1; i <= size; i++) 
    heap[i] = 8 - i;
    buildHeap(heap, size);
    heap[size + 1] = 8;
    size++;
    fixUp(heap, size, size);
    heapSort(heap, size);
    }
    
    
    
    //哈希:用于进行信息的快速查找
    //      1. 提取信息的特征值
    //      2. 将特征值和信息的存储地址进行关联
    
    #include <iostream>
    using namespace std;
    
    #define SIZE 100000  //根据需要更改
    typedef struct Node{
        int key;
        struct Node * next;
        struct Node * prev;
    }Node;
    
    Node HashTable[SIZE + 10];
    Node HashPool[SIZE+10]; //根据题意判断需不需要hashpool
    int HashIndex = 0;
    
    Node * getNewNode(){
        return &HashPool[HashIndex++];
    }
    
    void insertNode(int key, Node * newNode){
        Node * head = &HashTable[key];
        newNode->prev = head;
        newNode->next = head->next;
        head->next = newNode;
               newNode->next->prev = newNode;
    }
    
    void initHash(int N){
        HashIndex = 0; //reset hash pool
        for(int i = 0; i < N; i++){
        HashTable[i].prev = &HashTable[i];
        HashTable[i].next = &HashTable[i];
        }
    }
    
    int getKey(int val){
        return val % (SIZE + 3);
    }
    
    Node * searchNode(Node * node){
    int key = getKey(node->key);
    Node * x = HashTable[key].next;
    while(x != &HashTable[key] && x->key != node->key){
            x = x->next;
        }
        if(x != &HashTable[key])
            return x;
        else  return NULL;
    }
    
    void deleteNode(Node * node){
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    
    
    int main(){
    
    initHash(100);
    for(int i = 0; i < 100; i++){
        Node * newNode = getNewNode();
    newNode->key = i;
        int hashKey = getKey(i);
        insertNode(hashKey, newNode);
        Node * node = searchNode(newNode);
        cout << node->key << endl;
        }
        return 0;
    }
    
    //二分查找
    int bisearch(int number[], int find) {
        int low, mid, upper;
        low = 0;
        upper = MAX - 1;
        while(low <= upper) {
            mid = (low+upper) / 2;
            if(number[mid] < find)
                low = mid+1;
            else if(number[mid] > find)
                upper = mid - 1;
            else
                return mid;
       }
        return -1;
    }
    
    //快速排序
    void quicksort(int left,int right) 
    { 
      int i,j,t,temp; 
      if(left>right) 
          return; 
                                    
      temp=a[left]; //temp中存的就是基准数 
      i=left; 
      j=right; 
      while(i!=j) 
      {          //顺序很重要,要先从右边开始找 
             while(a[j]>=temp && i<j) 
                            j--; 
                  //再找右边的 
             while(a[i]<=temp && i<j) 
                          i++; 
                 //交换两个数在数组中的位置 
               if(i<j){ 
                         t=a[i]; 
                        a[i]=a[j]; 
                        a[j]=t; 
                       } 
       } 
        //最终将基准数归位 
        a[left]=a[i]; 
        a[i]=temp; 
                                 
    quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程 
    quicksort(i+1,right);//继续处理右边的, 这里是一个递归的过程 
    } 
    
    
    //二叉树:
    基本性质:
    性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)。
    性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。
    性质3:包含n个结点的二叉树的高度至少为log2 (n+1)。
    性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1//二叉搜索树
    #include<iostream>
    using namespace std;
    
    struct node{
        int val;
    node *lch, *rch, *parent;
    };
    
    //插入节点
    node *insert(node *p, int x){
    if( p == NULL){
         //node *q = new node;
        node *q = (node *)malloc(sizeof(node));
        q->val = x;
        q->lch = q->rch = NULL;
        return q;
        }else{
        if( x < p->val )
        p->lch = insert(p->lch, x);
        else
    p->rch = insert(p->rch, x);
            return p;
        }
    }
    
    //查找节点
    node *find(node *p, int x){
    if( p == NULL || p->val == x)
            return p;
    //递归
    if( x < p->val)
        find(p->lch, x);
    else
    find(p->rch, x);
        //非递归
    while((p != NULL) && (p->val != x)){
    if( x < p->val)
    p = p->lch;
    else
    p = p->rch;
    }
    return p;
    }
    
    //删除节点,返回根节点
    node *remove(node *p, int x){
       if( p == NULL)  return NULL;
       else if( x < p->val)  p->lch = remove( p->lch, x);
       else if( x > p->val)  p->rch = remove(p->rch, x);
       else if( p->lch == NULL){
       node *q = p->rch;
       delete p;
       return q;
       }
       else if(p->lch->rch == NULL){
       node *q = p->lch;
       q->rch = p->rch;
       delete p;
       return q;
       }
       else{     //左右都不为空
          node *q;
      for( q = p->lch; q->rch->rch != NULL; q= q->rch);  
      //把需要删除节点的左儿子子孙中的最大值提到删除节点位置
       node * r = q->rch;
    q->rch = r->lch;//提升节点的左子树作为其父节点右子树
     r->lch = p->lch;
     r->rch = p->rch;
     delete p;
     return r;
       }
       return p;
    }
    //前中后序遍历
    
    node *maximum(node *node){
        if(node == NULL)    return NULL;
    while(node->rch != NULL)
        node = node->rch;
        return node;
    }
    
    node *minimum(node *node){
       if(node == NULL)  return NULL;
       while(node->lch != NULL)
       node = node->lch;
       return node;
    }
    
    //前驱和后继节点( 中序遍历 )
    node *predecessor(node *x){
    //x存在左孩子,前驱为"以其左孩子为根的树的最大节点"
    if( x->lch != NULL)
    return maximum(x->lch);  
    //x不存在左孩子,前驱为:
    // 1)x是"一个右孩子",则"x的前驱结点"为 "它的父结点"
    // 2)x是"一个左孩子",则查找"x的最低的父结点,并且该节点作为该父结点右孩子",找到的这个"最低的父结点"就是"x的前驱结点"
    node *y = x->parent;
    while( (y != NULL) && (x == y->lch)){
        x = y;
        y = y->parent;
    }
        return y;
    }
    
    node *successor(node *x){
    //x存在右孩子,前驱为"以其右孩子为根的树的最小节点"
    if(x->rch != NULL)
        return minimum(x->rch);
    //x不存在右孩子:
    //1)x是"一个左孩子",则"x的后继结点"为 "它的父结点"
    //2)x是"一个右孩子",则查找"x的最低的父结点,并且该节点作为该父结点左孩子",找到的这个"最低的父结点"就是"x的前驱结点"
    node *y = x->parent;
    while(( y != NULL )&&(x == x->rch)){
           x = y;
           y = y->parent;
        }
        return y;
    }

    //单源最短路径问题(Dijikstra算法)
    //N : 结点数量
    //source: 起始结点下标

    int matrix[N][N]; //存储图的二维数组 boolean flagFinal[N]; //标志位 flagFinal[i]为 true //代表从 source 源点到 i 结点的最短路径已经计算得到 int result[N]; //存储最终结果 result[i]代表从 source 源点到 i 结点最短路径的值 void Dijkstra() { //初始化赋值 for (int i = 1; i <= N; i++) { result[i] = matrix[source][i]; flagFinal[i] = false; } //起始结点特殊处理 (到自身无需计算) result[source] = 0; flagFinal[source] = true; //遍历 N-1 次 for (int count = 1; count < N; count++) { //从剩余结点中,寻找距离 source 点最短的结点 //记录其下标 minDisLoc int tmpDis = INF; int minDisLoc = 0; //初始化下标为 0 (结点下标 1...N ) for (int i = 1; i <= N; i++) { if ((false == flagFinal[i]) && (result[i] < tmpDis)) { tmpDis = result[i]; minDisLoc = i; } } //找到本轮距离 source 最短的结点 下标 minDisLoc if (minDisLoc != 0) //更新 minDisLoc 结点标志位 { flagFinal[minDisLoc] = true; //更新各个结点的 result(距离 source 源点的距离) for (int i = 1; i <= N; i++) { if (false == flagFinal[i]) { //如果 minDisLoc 结点加入 //可以使i 结点距离 source 变短(result[i]变小),即更新 result[i] if (result[minDisLoc] + matrix[minDisLoc][i] < result[i]) { result[i] = result[minDisLoc] + matrix[minDisLoc][i]; } } } } } } ↓ 最小生成树(Prime算法) #define N 100 int matrix[N][N]; //最小生成树信息 int treeLenthResult = 0; //最终生成的最小生成树 边的权值之和 int minDis[N]; int closeVertex[N]; void Prime(){ //设置起始结点下标是0 (从顶点0开始构造) //初始化minDis for (int i = 0; i < N; i++) { minDis[i] = matrix[i][0]; closeVertel[i] = 0; } //起始结点初始化 minDis[0] = 0; closeVertel[0] = 0; //N-1次遍历,每次都从集合N中找到一个结点,距离集合Y中所有结点值最小 for (int i = 1; i < N; i++) { int tmpDis = INF; int tmpLoc = -1; for (int j = 0; j < N; j++) { //minDis[j] != 0 --> j结点不在当前的生成树中 if ((minDis[j] != 0) && (minDis[j] < tmpDis) ) { tmpDis = minDis[j]; tmpLoc = j; } } if (tmpLoc != -1) { //tmpLoc结点 是本轮循环中找到的目标结点 //更新当前得到生成树边的权值之和 treeLenthResult += tmpDis; } //tmpLoc结点从N结合移至Y集合 minDis[tmpLoc] = 0; //更新N集合中剩余的其他结点 for (int j = 0; j < N; j++) { if (minDis[j] > matrix[j][tmpLoc]) { minDis[j] = matrix[j][tmpLoc]; closeVertex[j] = tmpLoc; //此时,j结点距离Y集合中 tmpLoc结点最近 } } } }
  • 相关阅读:
    python
    在liunx环境下安装python
    解决用navicate远程连接数据库出现1045
    mysql的监控及优化
    mysql基础
    linux基础学习
    Effective c++ 第一章 让自己习惯C++
    读前感
    socket编程:客户端与服务器间的连接以及各函数的用法
    生成任意区间的随机数
  • 原文地址:https://www.cnblogs.com/chenyready/p/7986580.html
Copyright © 2011-2022 走看看