//单链表 constint N = 100010//就实际工程而言,定死可能不太优美,注意优化方案 int e[N];// store the value of the nodes int ne[N];// store the ptrs of next node int head;// store the index of head node int idx;// store the current available index
voidinit(){ head = -1;//注意:一开始链表为空,使用-1来辨识空结点 idx = 0; }
数据操纵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//insert to the head of the list voidadd_to_head(int x){ e[idx] = x; ne[idx] = head; head = idx++; } //insert the node after the k(index) node voidinsert_k(int k, int x){ e[idx] = x; ne[idx] = ne[k]; ne[k] = idx++; } //remove the node after the k(index) node voidremove_k(int k){ ne[k] = ne[ne[k]]; }
voidremove_l2(){ int pre = -1; int cnt=0; int cu = head; while(ne[cu]!=-1){ cnt++; if(cnt>1){ if(pre==-1) pre = head; else pre = ne[pre]; } cu = ne[cu]; } remove_k(pre); }
双链表
数据准备与初始化
1 2 3 4 5 6 7 8 9
int e[N]; int l[N]; //store the pre idex of current node int r[N]; //store the next idex of current node int idx; // store the current available node voidinit(){ r[0]=1; // 默认0号点为左边界,1号点为右边界 l[1]=0; idx = 2; }
// insert a node at the head of the list voidinsert_left(int x){ insert_k_right(0,x); } //insert a node at the end of the list voidinsert_right(int x){ insert_k_left(1,x); } //insert a node to the k(index) node 's left voidinsert_k_left(int k, int x){ insert_k_right(l[k],x); } //insert a node to the k(index) node 's right voidinsert_k_right(int k, int x){ e[idx] = x; r[idx] = r[k]; l[idx] = k; l[r[k]]=idx; r[k] = idx++; } // delete the k(index) node voiddelete_k(int k){ l[r[k]] = l[k]; r[l[k]] = r[k]; }
栈
先进后出
数据准备与初始化
1 2
int stk[N]; int tt=0;
数据操纵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//push to the top of stack voidpush(int x){ stk[++tt]=x; } //pop the top of the stack voidpop(){ if(tt>0) tt--; } //check if the stack is empty boolisEmpty(){ if(tt) returnfalse; elsereturntrue; } //query the top of the stack inttop(){ return stk[tt]; }
char str[N]; // add a string to the trie voidinsert(char str[]){ if(!str[0]) return; int cu = 0; for(int i=0;str[i];i++){ int k = str[i]-'A'; if(!son[cu][k]) son[cu][k] = idx++; cu = son[cu][k]; } cnt[cu]++; } // query the number of occurances of the string in the trie intfind_occur(char str []){ if(!str[0]) return0; int cu = 0; for(int i=0;str[i];i++){ int k = str[i]-'A'; if(!son[cu][k]) return0; cu = son[cu][k]; } return cnt[cu]; }
int fa[N]; // store the parent index of each node // only the root node has the property of fa[root]=root' voidinit(){ int num; cin>>num; for(int i=1;i<=num;i++) fa[i]=i; }
数据操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// find the set(root) index which num x is in intfind_root(int x){ //if current node is not root if(fa[x]!=x) fa[x]=find_root(fa[x]); // path compression return x; } // combine two sets which num a/b is in voidcombine(int a, int b){ int r_a = find_root(a); int r_b = find_root(b); if(r_a != r_b) fa[a]= b; } // query whether two num are in the same set boolinSameSet(int a, int b){ returnfind_root(a)==find_root(b); }
堆
在STL中也称为优先队列priority queue
数据准备与初始化
1 2 3 4 5 6
int heap[N];//heap is a 完全二叉树 int size; int cnt; // cnt the num of insert int cti[N],itc[N]; // preserve a count to index mapping and a index to count mapping // cause 2*i is the left node index and 2*i+1 is the right node index // so we have to start at the index 1
// swap voidmyswap(int x, int y){ swap(heap[x],heap[y]); swap(cti[itc[x]],cti[itc[y]]); swap(itc[x],itc[y]); } // build a heap voidbuildHeap(){ for(int i = size/2;i;i--){ down(i); } } // up voidup(int x){ if(x/2 && heap[x/2]>heap[x]){ myswap(x/2,x); up(x/2); } } // down voiddown(int x){ int min_i = x; if(2*x<=size && heap[min_i]>heap[2*x]) min_i = 2*x; if(2*x+1<=size && heap[min_i]>heap[2*x+1]) min_i = 2*x + 1; if(min_i!=x) { myswap(min_i,x); down(min_i); } } // insert a num voidinsert(int num){ heap[++size] = num; itc[size] = ++cnt; cti[cnt] = size; up(size); } // output the min num of the heap intmin_val(){ return heap[1]; } // delete the min num of the heap voiddelete_min(){ myswap(1,size--); down(1); } // delete the kth insert num voiddelete_k(int k){ // put the num at position size of the heap(end) to the position cti[k] // if we don't know the itc(index to count mapping) // we can't update the new cti[itc[size]] which is actually cti[k] // so we need a two way mapping int tmp = cti[k]; // store this value because the function below it may change its value myswap(tmp, size--); up(tmp),down(tmp); } // modify the kth insert num to x voidmodify_k(int k, int x){ heap[cti[k]] = x; up(cti[k]),down(cti[k]); }
// find the index where the num should be(exists if h[index] not null) intfind(int x){ int k = (x%N+N)%N; // not to make it negative, compute the hash Which is often the mod operation. while(h[k]!=null && h[k]!=x){ k++; if(k==N) k=0; } return k; } // query whether the num is in the hash table boolhasNum(int x){ if(h[find(x)]!=null) returntrue; elsereturnfalse; } // insert a num into hash table voidinsert(int x){ if(!hasNum(x)) h[find(x)]= x; }
拉链法
数据准备与初始化
1 2 3
int h[N] // N = 100003 int e[N],ne[N],idx; memset(h,-1,sizeof h);//-1代表为空
数据操纵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//拉链法 // insert a num into hash table, can be duplicate in this situation intinsert(int x){ int k = (x%N+N)%N; e[idx] = x; ne[idx] = h[k]; h[k]= idx++; } // query whether the num is in the hash table boolhasNum(int x){ int k = (x%N+N)%N; int cu = h[k]; while(cu!=-1) { if(e[cu]==x) returntrue; cu = ne[cu]; } returnfalse; }
Post title:coding笔记:典型数据结构之数组模拟浅析
Post author:sixwalter
Create time:2023-08-05 11:14:26
Post link:https://coelien.github.io/2023/08/05/coding-solution/常用数据结构/
Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.