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