跳到主要内容

3 篇博文 含有标签「算法」

查看所有标签

july-class-01(字符和字符串)

· 阅读需 4 分钟

Huffman编码

Huffman编码是一种无损压缩编码方案。

思想:根据源字符出现的概率对字符编码,概率高的字符使用较短的编码,概率低的使用较长的编码,从而使得编码后的字符串长度期望最小。

Huffman编码是一种贪心算法:每次总选择两个最小概率的字符节点合并

移除空格算法

时间复杂度O(n),空间复杂度O(1)


#include <iostream>
#include <stdio.h>
using namespace std;


void RemoveBlank(char* pString){
int j = 0;
for(int i= 0;pString[i]!='\0';i++){
if(pString[i] != ' '){
if(i != j){
pString[j] = pString[i];
}
j++;
}
}
pString[j] = 0;
}

int main(){
char str [] = "I have Dream o";
RemoveBlank(str);
cout<<str<<endl;
return 0;
}

找大数

#include <iostream>
#include <stdio.h>
using namespace std;
void FindMax(const int* a, int size,int& nMax,int& nSecondMax){
for(int i = 0;i<size;i++){
if(nMax < a[i]){
nSecondMax = nMax;
nMax = a[i];
}else if(nSecondMax < a[i]){
nSecondMax = a[i];
}
}
}

int main(){
int a [] = {1,5,4,8,3,2,9,14};
int nMax=0;
int nSecondMax = 0;
FindMax(a,sizeof(a)/sizeof(int),nMax,nSecondMax);
printf("max=%d,secondMax = %d\n",nMax,nSecondMax);
return 0;
}

Huffman 编码Java版

 public static class HuffmanNode {
public HuffmanNode() {
// TODO Auto-generated constructor stub
}

public int weight = 0;
public int parent = 0;
public int leftNode = 0;
public int rightNode = 0;
}

mian函数

public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "when I was young I'd listen to the radio waiting for my favorite songs "
+ "when they played I'd sing along,"
+ "it make me smile."
+ "those were such happy times and not so long ago"
+ "how I wondered where they'd gone."
+ "but they're back again just like a long lost friend"
+ "all the songs I love so well."
+ "every shalala every wo'wo"
+ "still shines."
+ "every shing-a-ling-a-ling "
+ "that they're starting" + "to sing so fine";

int[] weight = new int[N];
ArrayList<Integer> list = new ArrayList<Integer>();
CalcFrequency(str, weight);
weight[(int) '\t'] = 0;
CalcExistChar(weight, list);
int N2 = list.size();
ArrayList<ArrayList<Character>> node = new ArrayList<ArrayList<Character>>(N2);
HuffmanCoding(weight, N2, node);
printNode(node,list);
System.out.println("complete");
}

计算字符权重

	static void CalcFrequency(String str, int[] arr) {
for (int i = 0; i < str.length(); i++) {
arr[(int) str.charAt(i)]++;
}
}

将字符记录在list中

	static void CalcExistChar(int[] arr, ArrayList<Integer> list) {
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
list.add(i);
if (i != j) {
arr[j] = arr[i];
j++;
}
}
}
}

核心代码

static void HuffmanCoding(int[] weight, int N,
ArrayList<ArrayList<Character>> node) {
if (N <= 0)
return;
int m = 2 * N + 1;
// 初始化树
ArrayList<HuffmanNode> huffmanTree = new ArrayList<HuffmanNode>();
for (int i = 0; i < m; i++) {
HuffmanNode huffmanNode = new HuffmanNode();
huffmanTree.add(huffmanNode);
}
for (int i = 0; i < N; i++) {
huffmanTree.get(i).weight = weight[i];
}
// 找出2个权重最小将其组合
for (int i = N; i < m; i++) {
FindMin(huffmanTree, i);
if (s1 == -1 || s2 == -1)
continue;
huffmanTree.get(s1).parent = huffmanTree.get(s2).parent = i;
huffmanTree.get(i).leftNode = s1;
huffmanTree.get(i).rightNode = s2;
huffmanTree.get(i).weight = huffmanTree.get(s1).weight
+ huffmanTree.get(s2).weight;
}
//根据建好的huffman树从叶子到根,计算每个叶子节点的编码
int nParent;
int curNode;
for (int i = 0; i < N; i++) {
ArrayList<Character> cur = new ArrayList<Character>();
nParent = huffmanTree.get(i).parent;
curNode = i;
while (nParent != 0) {
if (huffmanTree.get(nParent).leftNode == curNode) {
cur.add('0');
} else {
cur.add('1');
}
curNode = nParent;
nParent = huffmanTree.get(curNode).parent;
}
Collections.reverse(cur);
node.add(cur);
}
}

打印树编码

	static void printNode(ArrayList<ArrayList<Character>> code,
ArrayList<Integer> charList) {
for (int i = 0; i < code.size(); i++) {
printCode((char) charList.get(i).intValue(), code.get(i));
}
}

static void printCode(char c, ArrayList<Character> code) {
System.out.println("char=" + c + ":");
for (int i = 0; i < code.size(); i++) {
System.out.print(code.get(i));
}
System.out.println();
}

july-class-02(树)

· 阅读需 2 分钟

二叉树遍历

前序遍历:根左右 中序遍历:左根右 后序遍历:左右根

层次遍历:使用队列

//先序遍历
void PreOrderTraverse(BiTree T){
if(T){
printf("%c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//中序遍历
void InOrderTraverse(BiTree T){
if(T){
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
}

//后序遍历
void PostOrderTraverse(BiTree T){
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c",T->data);
}
}

二叉树的深度

int Depth(BiTree T){
if(!T) return 0;
int d1=Depth(T->lchild);
int d2=Depth(T->rchild);
return (d1>d2?d1:d2)+1;
}

二叉树的节点数

int NodeCount(BiTree T){
if(!T) return 0;
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}

二叉树的叶子节点数

int LeafCount(BiTree T){
if(!T) return 0;
if(!T->lchild && !T->rchild) return 1;
return LeafCount(T->lchild)+LeafCount(T->rchild);
}

判断两颗二叉树是否相同

bool IsSameTree(BiTree T1,BiTree T2){
if(!T1 && !T2) return true;
if(!T1 || !T2) return false;
if(T1->data!=T2->data) return false;
return IsSameTree(T1->lchild,T2->lchild)&&IsSameTree(T1->rchild,T2->rchild);
}

july-class-03(查找与排序)

· 阅读需 2 分钟

折半查找

int BinarySearch(int *a,int n,int key){
int low=1,high=n,mid;
while(low<=high){
mid=(low+high)/2;
if(key<a[mid]){
high=mid-1;
}else if(key>a[mid]){
low=mid+1;
}else{
return mid;
}
}
return 0;
}

冒泡排序

void BubbleSort(int *a,int n){
int i,j,flag;
for(i=1;i<n;i++){
flag=0;
for(j=0;j<n-i;j++){
if(a[j]>a[j+1]){
a[j]=a[j]^a[j+1];
a[j+1]=a[j]^a[j+1];
a[j]=a[j]^a[j+1];
flag=1;
}
}
if(flag==0) break;
}
}

快速排序

void QuickSort(int *a,int low,int high){
if(low<high){
int pivotloc=Partition(a,low,high);
QuickSort(a,low,pivotloc-1);
QuickSort(a,pivotloc+1,high);
}
}

int Partition(int *a,int low,int high){
int pivotkey=a[low];
while(low<high){
while(low<high && a[high]>=pivotkey) --high;
a[low]=a[high];
while(low<high && a[low]<=pivotkey) ++low;
a[high]=a[low];
}
a[low]=pivotkey;
return low;
}

直接插入排序

void InsertSort(int *a,int n){
int i,j;
for(i=2;i<=n;i++){
if(a[i]<a[i-1]){
a[0]=a[i];
for(j=i-1;a[0]<a[j];j--){
a[j+1]=a[j];
}
a[j+1]=a[0];
}
}
}

希尔排序

void ShellSort(int *a,int n){
int i,j;
int dk=n/2;
while(dk>=1){
for(i=dk+1;i<=n;i++){
if(a[i]<a[i-dk]){
a[0]=a[i];
for(j=i-dk;j>0 && a[0]<a[j];j-=dk){
a[j+dk]=a[j];
}
a[j+dk]=a[0];
}
}
dk=dk/2;
}
}

堆排序

void HeapAdjust(int *a,int s,int m){
int rc=a[s];
for(int j=2*s;j<=m;j*=2){
if(j<m && a[j]<a[j+1]) j++;
if(rc>=a[j]) break;
a[s]=a[j];
s=j;
}
a[s]=rc;
}

void HeapSort(int *a,int n){
int i;
for(i=n/2;i>0;i--){
HeapAdjust(a,i,n);
}
for(i=n;i>1;i--){
a[1]=a[1]^a[i];
a[i]=a[1]^a[i];
a[1]=a[1]^a[i];
HeapAdjust(a,1,i-1);
}
}