基础算法总结

#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结点最近 } } } }

 

转载于:https://www.cnblogs.com/chenyready/p/7986580.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值