链表
链表逆序
1递归
typedef struct node
{ elementType element;
struct node* next;
}node;
typedef struct firstNode
{
int total;
node* next;
}firstNode;
node* reversel(node* node)
{
struct node* p=node;
if(node==NULL||node->next==NULL)
return node;
p=reversel(node->next);
node->next->next=node;
node->next=NULL;
return p;
}
2循环(首插)
void reverse(headerList* list)
{
node* head=list->head;
node* p=head->link;
node* temp;
head->link=NULL;
while(p)
{
temp=p;
p=p->link;
temp->link=head;
head=temp;
}
list->head=head;
}
3堆栈新建一个
链表合并
O(n*m)
node* merge(firstNode* node1,firstNode* node2)
{
node* Long=node1->total>=node2->total?node1->next:node2->next;
node* Short=node1->total<node2->total?node1->next:node2->next;
while(Short)
{
node* LP=Long;
node* SP=Short;
while(LP->next&&LP->element<Short->element)
{ if(LP->next->element>Short->element)
break;
LP=LP->next;
}
Short=Short->next;
if(LP->next==NULL)
{
LP->next=SP;
SP->next=NULL;
continue;
}
if(LP->element>SP->element)
{
SP->next=Long;
Long=SP;
continue;
}
if(LP->element==SP->element)
continue;
SP->next=LP->next;
LP->next=SP;
}
return Long;
}
O(n+m)
firstNode* merge(firstNode* node1,firstNode* node2)
{
//算法核心在于将最小的放到第三个串后面
firstNode* p=(firstNode*)malloc(sizeof(firstNode));
node* Pa=node1->next,*Pb=node2->next,*Pc=(node*)malloc(sizeof(node));
p->next=Pc;
node* temp=Pc;
while(Pa&&Pb)
{
if(Pa->element<=Pb->element)
{
Pc->next=Pa;
//这一步等价于Pc=Pc->next
Pc=Pa;
Pa=Pa->next;
}
else{
Pc->next=Pb;
//这一步等价于Pc=Pc->next
Pc=Pb;
Pb=Pb->next;
}
}
Pc->next=Pa?Pa:Pb;
p->next=temp->next;
free(next);
return p;
}
链表排序
O(n^2)
void sort(headerList *list)
{
node* p=list->head;
node* q=list->head;
node* min;
int temp;
while(q)
{
min=q;
p=q->link;
while(p)
{
if(p->data<min->data)
min=p;
p=p->link;
}
temp=q->data;
q->data=min->data;
min->data=temp;
q=q->link;
}
}
多项式
结构体
typedef struct pNode
{
//系数
int coef;
//指数
int exp;
struct pNode* link;
}pNode;
typedef struct
{
pNode* head;
}polynominal;
创建
//下标为指数,值为系数
polynominal* create(int a[],int length)
{
polynominal* p1=(polynominal*)malloc(sizeof(polynominal));
pNode* p=(pNode*)malloc(sizeof(pNode));
p1->head=p;
for(int i=0;i<length-1;i++)
{
p->coef=a[i];
p->exp=i;
p->link=(pNode*)malloc(sizeof(pNode));
p=p->link;
}
p->coef=a[length-1];
p->exp=length-1;
p->link=NULL;
return p1;
}
打印
void print(polynominal* head)
{
pNode* p=head->head;
while(p)
{
printf("系数为%d,指数为%d\t",p->coef,p->exp);
p=p->link;
}
printf("\n");
}
删除
void deletePolynominal(polynominal * head)
{
pNode* p=head->head;
free(head);
pNode* q;
while(p)
{
q=p;
p=p->link;
free(q);
}
}
合并多项式
polynominal* merge(polynominal *h1,polynominal* h2)
{
polynominal* h3=(polynominal*)malloc(sizeof(polynominal));
pNode* p1=h1->head,*p2=h2->head,*p3=(pNode*)malloc(sizeof(pNode)),*temp=p3;
p3->coef=0;
p3->exp=1000000000000;
while(p1&&p2)
{
if(p1->exp<p2->exp)
{
p3->link=p1;
p3=p1;
p1=p1->link;
continue;
}
if(p1->exp==p2->exp)
{
p3->link=p1;
p3=p1;
p3->coef+=p2->coef;
p1=p1->link;
p2=p2->link;
continue;
}
if(p1->exp>p2->exp)
{
p3->link=p2;
p3=p2;
p2=p2->link;
}
}
p3->link=p1?p1:p2;
h3->head=temp->link;
free(temp);
return h3;
}
合并多项式(不改变原来的)
//每个节点都是新的
polynominal* mergeNew(polynominal *h1,polynominal* h2)
{
polynominal* h3=(polynominal*)malloc(sizeof(polynominal));
pNode* p1=h1->head,*p2=h2->head,*p3=(pNode*)malloc(sizeof(pNode)),*temp=p3;
p3->coef=0;
p3->exp=1000000000000;
while(p1&&p2)
{
if(p1->exp<p2->exp)
{
p3->link=new pNode;
p3->link->coef=p1->coef;
p3->link->exp=p1->exp;
p3=p3->link;
p1=p1->link;
continue;
}
if(p1->exp==p2->exp)
{
/*p3->link=new pNode;
p3->link->coef=p1->coef+p2->coef;
p3->link->exp=p1->exp;
p3=p3->link;*/
if(p1->coef+p2->coef)
{
p3->link=new pNode;
p3->link->coef=p1->coef+p2->coef;
p3->link->exp=p1->exp;
p3=p3->link;
}
p1=p1->link;
p2=p2->link;
continue;
}
if(p1->exp>p2->exp)
{
p3->link=new pNode;
p3->link->coef=p2->coef;
p3->link->exp=p2->exp;
p3=p3->link;
p2=p2->link;
}
}
//p3->link=p1?p1:p2;
pNode *p=p1?p1:p2;
while(p)
{
p3->link=new pNode;
p3->link->coef=p->coef;
p3->link->exp=p->exp;
p3=p3->link;
p=p->link;
}
p3->link=NULL;
h3->head=temp->link;
free(temp);
return h3;
}
多项式乘单项式
//不破坏原值
polynominal* multiplySingle(polynominal* h1,pNode* now)
{
pNode* p=h1->head;
polynominal* h2=(polynominal*)malloc(sizeof(polynominal));
pNode* p1=(pNode*)malloc(sizeof(pNode));
h2->head=p1;
while(p->link)
{
p1->coef=p->coef*now->coef;
p1->exp=p->exp+now->exp;
p1->link=(pNode*)malloc(sizeof(pNode));
p=p->link;
p1=p1->link;
}
p1->coef=p->coef*now->coef;
p1->exp=p->exp+now->exp;
p1->link=NULL;
return h2;
}
多项式相乘
polynominal* multiply(polynominal* h1,polynominal* h2)
{
pNode* p=h2->head;
polynominal* temp1=multiplySingle(h1,p),*temp2;
p=p->link;
while(p)
{
temp2=temp1;
temp1=mergeNew(temp1,multiplySingle(h1,p));
p=p->link;
deletePolynominal(temp2);
}
return temp1;
}
循环队列
#include<stdio.h>
#include<stdlib.h>
typedef struct{
//前一个
int front;
//尾
int rear;
int maxSize;
int * element;
}Queue;
void creatQueue(Queue* queue,int max)
{
queue->maxSize=max;
queue->element=(int*)malloc(queue->maxSize*sizeof(int));
queue->front=0;
queue->rear=0;
}
void print(Queue* queue)
{
for(int i=queue->front;i<=queue->rear;i++)
printf("%d",queue->element[i]);
}
int isFull(Queue *q)
{
if((q->rear+1)%q->maxSize==q->front)
return 1;
return 0;
}
int isEmpty(Queue*q)
{
if(q->front==q->rear)
return 1;
return 0;
}
void enter(Queue *q,int x)
{
if(isFull(q))
return;
q->rear=(q->rear+1)%q->maxSize;
q->element[q->rear]=x;
}
int out(Queue* q)
{
int x;
if(isEmpty(q))
return 0;
x=q->element[(q->front+1)%q->maxSize];
q->front=(q->front+1)%q->maxSize;
return x;
}
堆栈
后缀表达式求值
数值入栈,遇到操作符号弹出两个元素,先弹出来的为右,后为左,计算完毕后,结果入栈
public class juc {
public static int fun(char left1,char right1,char operator)
{
int result=0;
int left=Integer.parseInt(String.valueOf(left1));
int right=Integer.parseInt(String.valueOf(right1));
switch (operator) {
case '+':
result=left+right;
break;
case '-':
result=left-right;
break;
case'/':
result=left/right;
break;
case'*':
result=left*right;
break;
}
return result;
}
public static void main(String[] args) {
String s="642-/32*+";
Stack<Character> stack = new Stack<>();
stack.push('#');
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i)<='9'&&s.charAt(i)>='0') {
stack.push(s.charAt(i));
}else{
Character right = stack.pop();
Character left = stack.pop();
char c = (char) (fun(left, right, s.charAt(i)) + 48);
stack.push(c);
}
}
System.out.println(stack);
}
}
中缀转后缀
public class temp {
static String transfer(String source)
{
ArrayList<Character> list = new ArrayList<>();
Stack<Character> stack = new Stack<>();
stack.push('#');
//region设定优先级
HashMap<Character, Integer> icp = new HashMap<>();
HashMap<Character, Integer> isp = new HashMap<>();
icp.put('#', 0);
icp.put('(', 7);
icp.put('*', 4);
icp.put('/', 4);
icp.put('+', 2);
icp.put('-', 2);
icp.put(')', 1);
isp.put('#', 0);
isp.put('(', 1);
isp.put('*', 5);
isp.put('/', 5);
isp.put('+', 3);
isp.put('-', 3);
isp.put(')', 7);
//endregion
for (int i = 0; i < source.length(); i++) {
//数字抛出
if (Character.isDigit(source.charAt(i))) {
list.add(source.charAt(i));
System.out.println(stack+""+source.charAt(i));
continue;
}
//‘)’连续出栈到遇到‘(’,‘(’直接抛出
if (source.charAt(i)==')') {
while (stack.peek() != '(') {
list.add(stack.pop());
}
stack.pop();
System.out.println(stack+""+source.charAt(i));
continue;
}
//source中外比顶的内大,入栈
if (icp.get(source.charAt(i))>isp.get(stack.peek())){
stack.push(source.charAt(i));
System.out.println(stack+""+source.charAt(i));
continue;
}
//source中外比顶的内小于等于,连续出栈到比他小,然后入栈
if(icp.get(source.charAt(i))<=isp.get(stack.peek()))
{while (icp.get(source.charAt(i))<=isp.get(stack.peek()))
list.add(stack.pop());
stack.push(source.charAt(i));
System.out.println(stack+""+source.charAt(i));
continue;
}
}
//最后出栈至‘#’
while (stack.peek()!='#') {
list.add(stack.pop());
}
return list.toString();
}
public static void main(String[] args) {
System.out.println(transfer("1/(2-3)+4*5"));
}
}
递归
斐波那契数列求值优化(java实现)
public class juc {
public static HashMap<Long,Long> hashMap=new HashMap();
static {
hashMap.put(1L,1L);
hashMap.put(2L,1L);
}
public static Long old(Long x)
{
if(x==1||x==2)
return 1L;
return old(x-1)+old(x-2);
}
public static Long newfun(Long x)
{
if (hashMap.containsKey(x)) {
return hashMap.get(x);
}
Long result=newfun(x-1)+newfun(x-2);
hashMap.put(x,result );
return result;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(newfun(100L));
System.out.println("新"+ (System.currentTimeMillis()-start));
start=System.currentTimeMillis();
System.out.println(old(100L));
System.out.println("旧"+ (System.currentTimeMillis()-start));
}
}
字符串
KMP算法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//next数组下标为失配下标,对应值为失配后移动到的位置
void GetNext(char* p)
{
int pLen = strlen(p);
int *next=(int*)malloc(sizeof(int)*pLen);
//当第一个就失配,模式串指针已经是在头了,所以不能再移动,应该是i后移,对应j=-1,
//j++后也是0
int k = -1;
next[0] = k;
int j = 0;
// -1 j=0
//next[j]= 0 重合数为0
// K 最长
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
//j只向后面走,也就是说每移动一次都是求此时的K值
//k可以回溯,k代表前面有多少,如果前后缀匹配,k值也就是最大长度
//当P[k]==p[j]也就是说前后缀匹配的情况下,很容易推出前面一个也满足
//也就是K2=K1+1;此时比前一个多1
//因为在P[j]之前已经有P[0 ~ k-1] == p[j-k ~ j-1]
//我们的目的是用数学归纳法,来求解next数组的每个值。当前已经求到next[j],接着就
//应该求解next[j+1],此时就分两种情况,一种是:重复的字符串个数会增加,即所谓的
//p[k]=p[j],此时p[j+1]=k+1;即p[++j]=++k
if (k == -1 || p[j] == p[k])
{
//++j->前移
//先j+1原因是K值是失配项前面,不包含自己,但next下标为当前失配项。然后顺便前移一
//个算下一个的K值
next[++j] = ++k;
}
else
{
//相当于读取k前一个的最大串,如果还不行就再向前读取
//相当于去前缀里面查找能不能和后面匹配
//就是回溯,寻找上一个最大值
//首先要尽可能地从头上开始,若前缀中存在“对称”的相当于直接跳到前缀的前缀
//跳到了对称中心
//AB.....AB
//很显然我们要取前面的AB
k = next[k];
}
}
}
int KmpSearch(char* s, char* p)
{
int i = 0; //主串中字符的移动标识i
int j = 0; //子串中字符的移动标识j
int sLen = strlen(s);//主串字符个数
int pLen = strlen(p);//子串字符个数
int next[255]; //next数组,记录子串的移动规则
int* next=getNext(p);
while (i < sLen && j < pLen)
{
//如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j =
//next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)//在主串中找到子串
return i - j;
else
return -1;//没找到返回-1
}
int main()
{
//子串或模式串
char p[20] = "ABCDABD";
//主串
char s[30] = "BBC ABCDAB ABCDABCDABDE";//23个字符
printf("%d\n", KmpSearch(s, p));//15
system("pause");
return 0;
}
二叉树
结构体
typedef struct BiTree
{
char data;
struct BiTree* lChild;
struct BiTree* rChild;
}BiTree;
遍历
先序(根左右)
从上到下
第一次访问就输出
递归
void PreOrder(BiTree * t)
{
if(t)
{
printf("%c ",t->data);
PreOrder(t->lChild);
PreOrder(t->rChild);
}
}
循环
核心就是后填左节点
public void preOrderTraverseByWhile(TreeNode node){
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(node);
TreeNode currentNode;
while (!stack.isEmpty()) {
currentNode = stack.pop();
System.out.print(currentNode.data + " ");
if(currentNode.rightNode != null){
stack.push(currentNode.rightNode);
}
if (currentNode.leftNode != null) {
stack.push(currentNode.leftNode);
}
}
}
中序(左根右)
左枝从下到上
右枝从上到下
第二次访问输出
递归
void InOrder(BiTree * t)
{
if(t)
{
InOrder(t->lChild);
printf("%c ",t->data);
InOrder(t->rChild);
}
}
循环
public void inOrderTraverseByWhile(TreeNode node){
//将每个节点的所有左子树入栈
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode currentNode = node;
while (currentNode != null || !stack.isEmpty()) {
while(currentNode != null){
stack.push(currentNode);
currentNode = currentNode.leftNode;
}
if(!stack.isEmpty()){
//左子树,相对上一级为左子树,下一级为中
currentNode = stack.pop();
System.out.print(currentNode.data + "");
currentNode = currentNode.rightNode;
}
}
}
后序(左右根)
从下到上
第三次访问输出
递归
void PostOrder(BiTree * t)
{
if(t)
{
PostOrder(t->lChild);
PostOrder(t->rChild);
printf("%c ",t->data);
}
}
循环
public void afterOrderTraverseByWhile(TreeNode node){
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode rightNode = null;
TreeNode currentNode = node;
while (currentNode != null || !stack.isEmpty()) {
while(currentNode != null){
stack.push(currentNode);
currentNode = currentNode.leftNode;
}
currentNode = stack.pop();
//当上一个访问的结点是右孩子或者当前结点没有右孩子则访问当前结点
while(currentNode != null && (currentNode.rightNode == null || currentNode.rightNode == rightNode)){
System.out.print(currentNode.data + " ");
rightNode = currentNode;
if(stack.isEmpty()){
return;
}
currentNode = stack.pop();
}
stack.push(currentNode);
currentNode = currentNode.rightNode;
}
}
层次
从左到右
public void levelTraverse(TreeNode root) {
if (root == null) {
return;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.print(node.data+" ");
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
先序创建
BinaryTreeNode* PreCreate(BinaryTreeNode *t)
{
char c;
c=getchar();
if(c=='#')
{
t=NULL;
}
else
{
t=new BinaryTreeNode;
t->data=c;
t->LChild=PreCreate(t->LChild);
t->RChild=PreCreate(t->RChild);
}
return t;
}
深度优先遍历
public void depthOrderTraverse(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
System.out.print(node.val+" ");
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
}
求深度
public int getHeight(TreeNode node){
if (node == null) {
return 0;
}
int leftHeight=getHeight(node.leftNode);
int rightHeight=getHeight(node.rightNode);
return leftHeight<rightHeight?rightHeight+1:leftHeight+1;
}
节点数
int countNode(BinaryTreeNode * t)
{
int count=0;
if(t)
{ count++;
count+=countNode(t->LChild)+countNode(t->RChild);
}
return count;
}
求叶子节点数
int countLeafNode(BinaryTreeNode* t)
{
int count=0;
if(t)
{
if(t->LChild==NULL&&t->RChild==NULL)
count++;
count+=countLeafNode(t->LChild)+countLeafNode(t->RChild);
}
return count;
}
反转左右子树
void reverse(BinaryTreeNode* t)
{
if(t)
{
if(t->LChild!=NULL&&t->RChild!=NULL)
{
char temp=t->LChild->data;
t->LChild->data=t->RChild->data;
t->RChild->data=temp;
}
reverse(t->LChild);
reverse(t->RChild);
}
}
二叉堆
public static void upAdjust(int []array)
{
int childIndex= array.length-1;
int parentIndex=(childIndex-1)/2;
int temp=array[childIndex];
while (childIndex>0&&temp<array[parentIndex])
{
array[childIndex]=array[parentIndex];
childIndex=parentIndex;
parentIndex=(parentIndex-1)/2;
}
array[childIndex]=temp;
}
public static void downAdjust(int[] array,int parentIndex){
int temp=array[parentIndex];
int childIndex=2*parentIndex+1;
while (array.length > childIndex) {
//看看谁最小
if(childIndex+1<array.length&&array[childIndex+1]<array[childIndex])
childIndex++;
//比最小的小所以符合
if(temp<=array[childIndex])
break;
//下沉操作
array[parentIndex]=array[childIndex];
parentIndex=childIndex;
childIndex=childIndex*2+1;
}
array[parentIndex]=temp;
}
public static void bulidHeap(int[]array)
{
for (int i = (array.length-2)/2 ; i >=0 ; i--) {
downAdjust(array, i);
}
}
优先队列
public class PriorityQueue {
//size指向最后一位的后面
//例子:0,1,2,3,4,5,6,
//此时size下标为7
private int size;
private int[] array;
@Override
public String toString() {
return "PriorityQueue{" +
"array=" + Arrays.toString(array) +
'}';
}
public PriorityQueue(int size) {
array=new int[size];
}
public PriorityQueue(){
array=new int[32];
}
private void resize()
{
this.array= Arrays.copyOf(this.array, this.size*2);
}
public void upAdjust()
{
int childIndex=size-1;
int parentIndex=(childIndex-1)/2;
int temp=array[childIndex];
while (childIndex > 0 && temp < array[parentIndex]) {
array[childIndex]=array[parentIndex];
childIndex=parentIndex;
parentIndex=(parentIndex-1)/2;
}
array[childIndex]=temp;
}
public void downAdjust()
{
int parentIndex=0;
int childIndex=1;
int temp=array[0];
while (childIndex < size) {
if (childIndex+1<size&&array[childIndex]>=array[childIndex+1]) {
childIndex++;
}
if(array[childIndex]>temp)
break;
array[parentIndex]=array[childIndex];
parentIndex=childIndex;
childIndex=childIndex*2+1;
}
array[parentIndex]=temp;
}
public void enterQueue(int element)
{
if (size>=array.length) {
resize();
}
array[size++]=element;
upAdjust();
}
public int outQueue ()throws Exception
{
if (size<=0) {
throw new Exception("empty");
}
int result=array[0];
array[0]=array[--size];
downAdjust();
return result;
}
}
哈夫曼树
结构体
typedef struct{
char Data;
int w;//权值
int parent,lchild,rchild;
}HFMTNode;
创建哈夫曼树
HFMTNode* createHFMT(int n)
{
HFMTNode* hf=new HFMTNode[2*n];
for(int i=0;i<2*n;i++)
hf[i].lchild=hf[i].rchild=hf[i].parent=-1;
for(int i=1;i<=n;i++)
{
cout<<"数据"<<endl;
cin>>hf[i].Data;
cout<<"权重"<<endl;
cin>>hf[i].w;
}
for(int i=n+1;i<2*n;i++)
{//INT_MAX在limit.h包下定义
int minW1=INT_MAX;
int minW2=INT_MAX;
int rmin=-1;
int lmin=-1;
//寻找当前之前的最小值
for(int k=1;k<=i-1;k++)
{
//只有孤儿才可以
if(hf[k].parent==-1)
{
if(hf[k].w<minW1)
{
minW2=minW1;
minW1=hf[k].w;
rmin=lmin;
lmin=k;
}else if(hf[k].w<minW2)
{
minW2=hf[k].w;
rmin=k;
}
}
}
hf[i].w=hf[rmin].w+hf[lmin].w;
hf[i].lchild=lmin;
hf[i].rchild=rmin;
hf[rmin].parent=i;
hf[lmin].parent=i;
}
print(hf,n);
return hf;
}
打印哈夫曼树叶子节点信息
void print(HFMTNode hf[],int n)
{
for(int i=1;i<=2*n-1;i++)
cout<<"NOW:"<<i<<" "<<"parent:"<<hf[i].parent<<" "<<"rchild:"<<hf[i].rchild<<" "<<"lchild:"<<hf[i].lchild<<" "<<"w:"<<hf[i].w<<endl;
}
哈夫曼编码
char* encode(char c,HFMTNode *hf,int length)
{
int target,parentIndex;
char* result;
//最高n-1层
char* code=new char[length];
code[length-1]='\0';
int count=1;
for(int i=1;i<=length;i++){
if(hf[i].Data==c)
{
target=i;
break;
}
}
while(target!=-1)
{
parentIndex=hf[target].parent;
if(parentIndex==-1)
break;
if(hf[parentIndex].lchild==target)
{code[length-1-count]='0';}
else
{code[length-1-count]='1';}
count++;
target=parentIndex;
}
result =new char[count];
strcpy(result,&code[length-count]);
return result;
}
哈夫曼解码
char decode(HFMTNode *hf,char* code,int n)
{
int childIndex=2*n-1;;
while(*code!='\0')
{
if(*code=='1')
childIndex=hf[childIndex].rchild;
else
childIndex=hf[childIndex].lchild;
code++;
}
return hf[childIndex].Data;
}