ReviewForJob——二叉堆优先队列的实现(三种堆节点类型——int + struct HeapNode + struct HeapNode*)

【0】README

1)本文旨在给出 二叉堆优先队列的实现 的代码实现和分析, 而堆节点类型 不外乎三种: 一, 基本类型如int; 二,结构体类型 struct HeapNode; 三,结构体指针类型 struct HeapNode* 类型;

2)为什么要给出 结构体指针类型的 二叉堆实现 ? 因为 小生我在 实现 克鲁斯卡尔算法 求 最小生成树的时候,需要用到 二叉堆优先队列 选取 权值最小的边,所以要用到 结构体指针类型的 二叉堆实现, 哥子 今天一上午 也 没有 吧 kruskal alg 实现出来,原因就在于 结构体指针类型 的 二叉堆 没有 弄清楚;

3)本文末尾对三种堆节点类型的源码实现 进行了分析和比较;

4)for full source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6/review

5)wc, 刚才填了一个大坑,你懂的。

// for循环的 leftChild(index) <= size 必须要取 等号.for(temp = data[index]; leftChild(index) <= size; index = child){child = leftChild(index);if(child < size && data[child] < data[child+1]) // if 语句里的 child < size 不取等号.

【1】二叉堆基本操作

操作1)初始化堆;

操作2)基于上滤操作的插入操作;

操作3)基于下滤操作的删除最小值 (deleteMin);

操作4)decreaseKey 操作;

操作5)increaseKey 操作;


【2】基本类型(int)为堆节点的堆实现

1)堆结构体

// 堆节点类型为 int.
#define ElementType intstruct BinaryHeap;
typedef struct BinaryHeap *BinaryHeap;
struct BinaryHeap 
{int capacity;int size;	ElementType *array;		
};
2)源码实现

// judge whether the BinaryHeap is full or not , also 1 or 0 .
// you should know the element under index 0 don't store any content.
int isFull(BinaryHeap bh)
{return bh->size == bh->capacity - 1 ? 1 : 0 ;
}// judge whether the BinaryHeap is empty or not , also 1 or 0 
int isEmpty(BinaryHeap bh)
{return bh->size == 0 ? 1 : 0 ;
}void swap(ElementType *x, ElementType *y)
{ElementType temp;temp = *x;*x = *y;*y = temp;
}// get the left child of node under index with startup 1
int leftChild(int index)
{return index*2;
}// initialize binary heap with given capacity.
BinaryHeap initBinaryHeap(int capacity)
{BinaryHeap bh;ElementType *temp;bh = (BinaryHeap)malloc(sizeof(struct BinaryHeap));if(!bh) {Error("out of space, from func initBinaryHeap");        return NULL;}  bh->capacity = capacity;bh->size = 0;temp = (ElementType *)malloc(capacity * sizeof(ElementType));if(!temp) {Error("out of space, from func initBinaryHeap");        return NULL;} bh->array = temp;bh->array[0] = INT_MIN; // let bh->array[0] be the minimum integer.return bh;
}// Attention, the index of the heap starts from 1
// insert the value into binary heap based on percolateUp().
void insert(ElementType value, BinaryHeap bh)
{	if(isFull(bh)){Error("failed insertion , for the BinaryHeap is full, from func insert!");return ;	}bh->array[++bh->size] = value; // startup is 1 not 0.percolateUp(bh->size, bh);
}// percolating up the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1
void percolateUp(int i, BinaryHeap bh)
{	ElementType temp = bh->array[i];for(; temp < bh->array[i/2]; i/=2){bh->array[i] = bh->array[i/2];}bh->array[i] = temp;
}// delete minimal from binary heap based on percolateDown().
ElementType deleteMin(BinaryHeap bh)
{	ElementType minimum;ElementType *data;	if(isEmpty(bh)){Error("failed deleting minimum , for the BinaryHeap is empty, from func deleteMin !");return -1;	}data = bh->array;	minimum = data[1];swap(&data[1], &data[bh->size]); // &variable means nickname of the variablebh->size-- ; // size-- occurs prior to percolateDown(). percolateDown(1, bh) ;	return minimum;
} // percolating down the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1void percolateDown(int index, BinaryHeap bh){  ElementType *data;int size;ElementType temp;int child;data = bh->array;size = bh->size;for(temp = data[index]; leftChild(index) < size; index = child){child = leftChild(index);if(child < size && data[child] > data[child+1]){child++;}if(temp > data[child]){data[index] = data[child];}else{break;}}data[index] = temp;}// print binary heap.
void printBinaryHeap(BinaryHeap bh)
{int i;ElementType *temp;if(!bh){Error("printing execution failure, for binary heap is null, from func printBinaryHeap");	}temp = bh->array;for(i=1; i <= bh->size; i++){printf("\n\t index[%d] = ", i);				printf("%d", bh->array[i]);		}printf("\n");
}  // increase element's value
void increaseKey(int index, ElementType increment, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed increaseKey, since overstep the boundary! ");return ;}bh->array[index] += increment; // update the element under given indexpercolateDown(index, bh);
}//decreasing value of the element under index by increment
void decreaseKey(int index, ElementType decrement, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed decreaseKey, since overstep the boundary! ");return ;}bh->array[index] -= decrement; // update the element under given indexpercolateUp(index, bh);
}

3)测试用例

int main()
{int i;BinaryHeap bh;int capacity;int size;ElementType data[] =  {85, 80, 40, 30, 10, 70, 110};capacity = 15;size = 7;bh = initBinaryHeap(capacity);printf("\ninsert {85, 80, 40, 30, 10, 70, 110} into binary heap.");for(i = 0; i < size; i++){insert(data[i], bh);}	printBinaryHeap(bh);printf("\ninsert {100, 20, 90, 5} into binary heap\n");insert(100, bh);insert(20, bh);insert(90, bh);insert(5, bh);printBinaryHeap(bh);printf("\ndeleteMin from binary heap\n");deleteMin(bh);  printBinaryHeap(bh);    // other operations in bianry heap      printf("\nincreaseKey(2, 85, bh) [increaseKey(index, increment, binary heap)]\n");increaseKey(2, 85, bh);printBinaryHeap(bh);printf("\ndecreaseKey(9, 85, bh) [decreaseKey(index, decrement, binary heap)]\n");decreaseKey(9, 85, bh);printBinaryHeap(bh);return 0;
}

【3】结构体类型(struct HeapNode)为堆节点的堆实现

1)堆结构体

// 堆节点类型是结构体.
struct HeapNode; 
typedef struct HeapNode* HeapNode;
struct HeapNode
{int value;
};// 二叉堆的结构体.
struct BinaryHeap;
typedef struct BinaryHeap *BinaryHeap;
struct BinaryHeap 
{int capacity;int size;	HeapNode array; // 二叉堆实现为结构体数组.
};
// 堆节点类型是 结构体类型 而不是单纯的 int类型.
#define ElementType struct HeapNode 
2)源码实现

ElementType createElementType(int value)
{struct HeapNode node;node.value = value;return node;
}// judge whether the BinaryHeap is full or not , also 1 or 0 .
// you should know the element under index 0 don't store any content.
int isFull(BinaryHeap bh)
{return bh->size == bh->capacity - 1 ? 1 : 0 ;
}// judge whether the BinaryHeap is empty or not , also 1 or 0 
int isEmpty(BinaryHeap bh)
{return bh->size == 0 ? 1 : 0 ;
}void swap(ElementType *x, ElementType *y)
{ElementType temp;temp = *x;*x = *y;*y = temp;
}// get the left child of node under index with startup 1
int leftChild(int index)
{return index*2;
}// initialize binary heap with given capacity.
BinaryHeap initBinaryHeap(int capacity)
{BinaryHeap bh;ElementType *temp;bh = (BinaryHeap)malloc(sizeof(struct BinaryHeap));if(!bh) {Error("out of space, from func initBinaryHeap");        return NULL;}  bh->capacity = capacity;bh->size = 0;temp = (ElementType *)malloc(capacity * sizeof(ElementType));if(!temp) {Error("out of space, from func initBinaryHeap");        return NULL;} bh->array = temp;bh->array[0].value = INT_MIN; // update: let bh->array[0]->value be the minimum integer.return bh;
}// Attention, the index of the heap starts from 1
// insert the value into binary heap based on percolateUp().
void insert(ElementType e, BinaryHeap bh)
{		if(isFull(bh)){Error("failed insertion , for the BinaryHeap is full.");return ;	}bh->array[++bh->size] = e; // startup is 1 not 0.percolateUp(bh->size, bh);
}// percolating up the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1
void percolateUp(int i, BinaryHeap bh)
{	ElementType temp = bh->array[i];for(; temp.value < bh->array[i/2].value; i/=2) // update.{bh->array[i] = bh->array[i/2];}bh->array[i] = temp;
}// delete minimal from binary heap based on percolateDown().
ElementType deleteMin(BinaryHeap bh)
{	ElementType minimum;ElementType *data;				data = bh->array;	minimum = data[1];swap(&data[1], &data[bh->size]); // &variable means nickname of the variablebh->size-- ; // size-- occurs prior to percolateDown(). percolateDown(1, bh) ;	return minimum;
} // percolating down the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1void percolateDown(int index, BinaryHeap bh){  ElementType* array; int size;ElementType temp;int child;array = bh->array;size = bh->size;for(temp = array[index]; leftChild(index) <= size; index = child){child = leftChild(index);if(child < size && array[child].value > array[child+1].value){child++;}if(temp.value > array[child].value){array[index] = array[child];}else{break;}}array[index] = temp;}// print binary heap.
void printBinaryHeap(BinaryHeap bh)
{int i;ElementType *temp;if(!bh){Error("printing execution failure, for binary heap is NULL.");	}temp = bh->array;for(i = 1; i <= bh->size; i++){printf("\n\t index[%d] = ", i);				printf("%d", bh->array[i]);}printf("\n");
}  // increase element's value
void increaseKey(int index, int increment, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed increaseKey, since overstep the boundary! ");return ;}bh->array[index].value += increment; // update the element under given indexpercolateDown(index, bh);
}//decreasing value of the element under index by increment
void decreaseKey(int index, int decrement, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed decreaseKey, since overstep the boundary! ");return ;}bh->array[index].value -= decrement; // update the element under given indexpercolateUp(index, bh);
}

3)测试用例

// 堆节点是结构体类型.
int main()
{	BinaryHeap bh;int i, capacity, size;	int data[] =  {85, 80, 40, 30, 10, 70, 110};capacity = 15;size = 7;bh = initBinaryHeap(capacity);printf("\ninsert {85, 80, 40, 30, 10, 70, 110} into binary heap with heap node being struct.");for(i = 0; i < size; i++){insert(createElementType(data[i]), bh);}	printBinaryHeap(bh);printf("\ninsert {100, 20, 90, 5} into binary heap\n");insert(createElementType(100), bh);insert(createElementType(20), bh);insert(createElementType(90), bh);insert(createElementType(5), bh);printBinaryHeap(bh);printf("\ndeleteMin from binary heap\n");deleteMin(bh);  printBinaryHeap(bh);    // other operations in bianry heap      printf("\nincreaseKey(2, 85, bh) [increaseKey(index, increment, binary heap)]\n");increaseKey(2, 85, bh);printBinaryHeap(bh);printf("\ndecreaseKey(9, 85, bh) [decreaseKey(index, decrement, binary heap)]\n");decreaseKey(9, 85, bh);printBinaryHeap(bh);return 0;
}

【4】结构体类型指针(struct HeapNode*)为堆节点的堆实现

1)堆结构体

struct HeapNode; 
typedef struct HeapNode* HeapNode;
struct HeapNode
{int value;
};// 二叉堆的结构体.
struct BinaryHeap;
typedef struct BinaryHeap *BinaryHeap;
struct BinaryHeap 
{int capacity;int size;	HeapNode* array;  // 堆节点类型是结构体指针. 而优先队列是结构体指针数组.
};
// 堆节点类型是 结构体指针类型 而不是单纯的 int类型.
#define ElementType HeapNode 

2)源码实现

ElementType createElementType(int value)
{HeapNode node = (HeapNode)malloc(sizeof(struct HeapNode));if(node == NULL){Error("failed createElementType() for out of space.");        return NULL;}node->value = value;return node;
}// judge whether the BinaryHeap is full or not , also 1 or 0 .
// you should know the element under index 0 don't store any content.
int isFull(BinaryHeap bh)
{return bh->size == bh->capacity - 1 ? 1 : 0 ;
}// judge whether the BinaryHeap is empty or not , also 1 or 0 
int isEmpty(BinaryHeap bh)
{return bh->size == 0 ? 1 : 0 ;
}void swap(ElementType x, ElementType y)
{struct HeapNode temp;temp = *x;*x = *y;*y = temp;
}// get the left child of node under index with startup 1
int leftChild(int index)
{return index*2;
}// initialize binary heap with given capacity.
BinaryHeap initBinaryHeap(int capacity)
{BinaryHeap bh;ElementType* temp;bh = (BinaryHeap)malloc(sizeof(struct BinaryHeap));if(!bh) {Error("out of space, from func initBinaryHeap");        return NULL;}  bh->capacity = capacity;bh->size = 0;temp = (ElementType *)malloc(capacity * sizeof(ElementType));if(!temp) {Error("out of space, from func initBinaryHeap");        return NULL;} bh->array = temp;// bh->array[0] = INT_MIN; bh->array[0] = (ElementType)malloc(sizeof(struct HeapNode));if(bh->array[0] == NULL){Error("out of space, from func initBinaryHeap");        return NULL;}bh->array[0]->value = INT_MIN; return bh;
}// Attention, the index of the heap starts from 1
// insert the value into binary heap based on percolateUp().
void insert(ElementType e, BinaryHeap bh)
{		if(e == NULL){Error("failed insertion , for e is NULL.");return;}if(isFull(bh)){Error("failed insertion , for the BinaryHeap is full.");return ;	}bh->array[++bh->size] = e; // startup is 1 not 0.percolateUp(bh->size, bh);
}// percolating up the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1
void percolateUp(int i, BinaryHeap bh)
{	ElementType temp = bh->array[i];for(; temp->value < bh->array[i/2]->value; i/=2) // update.{bh->array[i] = bh->array[i/2];}bh->array[i] = temp;
}// delete minimal from binary heap based on percolateDown().
ElementType deleteMin(BinaryHeap bh)
{	ElementType minimum;ElementType* array;				array = bh->array;	minimum = array[1];swap(array[1], array[bh->size]); // &variable means nickname of the variablebh->size-- ; // size-- 在下滤函数执行之前发生.percolateDown(1, bh) ;	return minimum;
} // percolating down the element when its value is greater than children (minimal heap)//Attention: all of bh->array starts from index 1void percolateDown(int index, BinaryHeap bh){  ElementType* array; int size;ElementType temp;int child;array = bh->array;size = bh->size;for(temp = array[index]; leftChild(index) <= size; index = child){child = leftChild(index);if(child < size && array[child]->value > array[child+1]->value){child++;}if(temp->value > array[child]->value){array[index] = array[child];}else{break;}}array[index] = temp;}// print binary heap.
void printBinaryHeap(BinaryHeap bh)
{int i;if(!bh){Error("printing execution failure, for binary heap is NULL.");	return;}for(i=1; i <= bh->size; i++){printf("\n\t index[%d] = ", i);				printf("%d", bh->array[i]->value);		}printf("\n");
}  // increase element's value
void increaseKey(int index, int increment, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed increaseKey, since overstep the boundary! ");return ;}bh->array[index]->value += increment; // update the element under given indexpercolateDown(index, bh);
}//decreasing value of the element under index by increment
void decreaseKey(int index, int decrement, BinaryHeap bh)
{   if(index > bh->size || index < 1){Error(" failed decreaseKey, since overstep the boundary! ");return ;}bh->array[index]->value -= decrement; // update the element under given indexpercolateUp(index, bh);
}

3)测试用例

// 堆节点是结构体指针类型.
int main()
{	BinaryHeap bh;int i, capacity, size;	int data[] =  {85, 80, 40, 30, 10, 70, 110};capacity = 15;size = 7;bh = initBinaryHeap(capacity);printf("\ninsert {85, 80, 40, 30, 10, 70, 110} into binary heap.");for(i = 0; i < size; i++){insert(createElementType(data[i]), bh);}	printBinaryHeap(bh);printf("\ninsert {100, 20, 90, 5} into binary heap\n");insert(createElementType(100), bh);insert(createElementType(20), bh);insert(createElementType(90), bh);insert(createElementType(5), bh);printBinaryHeap(bh);printf("\ndeleteMin from binary heap\n");deleteMin(bh);  printBinaryHeap(bh);    // other operations in bianry heap      printf("\nincreaseKey(2, 85, bh) [increaseKey(index, increment, binary heap)]\n");increaseKey(2, 85, bh);printBinaryHeap(bh);printf("\ndecreaseKey(9, 85, bh) [decreaseKey(index, decrement, binary heap)]\n");decreaseKey(9, 85, bh);printBinaryHeap(bh);return 0;
}

【5】堆节点为 或者int类型 或者结构体类型 或者 结构体指针类型 的源码分析和总结 

1)注意在以上实现中, 哪些函数是相同的,哪些函数是不同的, 就算有些函数声明相同,但是函数体是不同的;

2)要知道 堆的第一个存储空间不用(index == 0):对于int 类型的处理方式是 设置 array[0]=INT_MIN, 对于 struct 类型的处理方式是 array[0].value = INT_MIN,对于 struct* 类型的处理方式是 array[0]->value = INT_MIN,这都是为了 上滤的时候 便于比较;而对于 array[0] 的初始化都是在 初始化堆中的函数完成的;

3)还有一个需要注意的是 swap() 函数:deleteMin() 函数 需要用到 swap()函数,因为 在 删除最小元元素的时候,是吧 第一个元素 和 最后一个元素进行交换,然后size--,然后再对 index=1 的元素进行下滤操作;所以 swap() 交换函数特别重要;

void swap(ElementType x, ElementType y) // struct HeapNode* 的 swap函数.(堆节点类型是 结构体指针类型)
{struct HeapNode temp;temp = *x;*x = *y;*y = temp;
}
void swap(ElementType *x, ElementType *y) // struct HeapNode 的swap函数.(堆节点类型是 结构体类型)
{ElementType temp;temp = *x;*x = *y;*y = temp;
}
void swap(ElementType *x, ElementType *y) // int 类型的swap函数(堆节点类型是 int基本类型)
{ElementType temp;temp = *x;*x = *y;*y = temp;
}
4)测试用例中,插入元素进堆,传入的参数不一样:虽然 他们的 insert 函数都是 void insert(ElementType value, BinaryHeap bh),对于 int类型来说, ElementType 就是 int, 对于 struct HeapNode 来说,ElementType 就是 struct HeapNode, 而对于 struct HeapNode* 来说, ElementType 就是  struct HeapNode*;所以你看到在不同测试用例中,除开 int 基本类型 都是要 创建 堆节点的,然后再传入;

ElementType createElementType(int value) // struct HeapNode 类型的 createElementType() 函数体
{struct HeapNode node;node.value = value;return node;
}
ElementType createElementType(int value) // struct HeapNode* 类型的 createElemnetType() 函数体. 是很不一样的,这是我们需要注意的.
{HeapNode node = (HeapNode)malloc(sizeof(struct HeapNode));if(node == NULL){Error("failed createElementType() for out of space.");        return NULL;}node->value = value;return node;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring boot(六):如何优雅的使用mybatis

总结 hibernate 和 mybatis 的区别 hibernate的特点是所有的sql都用java代码生成&#xff0c;不用跳出程序去&#xff08;看&#xff09;sql&#xff0c;发展到最顶端就是Spring data jpa了。 mybatis初期使用比较麻烦&#xff0c;需要各种配置文件、实体类、dao层映射关联、还…

Java中创建String的两道面试题及详解

转载自 Java中创建String的两道面试题及详解 我们知道创建一个String类型的变量一般有以下两种方法&#xff1a; String str1 "abcd";String str2 new String("abcd"); 那么为什么会存在这两种创建方式呢&#xff0c;它们在内存中的表现形式各有什么区别…

ReviewForJob——最小生成树(prim + kruskal)源码实现和分析

【0】README 1&#xff09;本文旨在给出 ReviewForJob——最小生成树&#xff08;prim kruskal&#xff09;源码实现和分析&#xff0c; 还会对其用到的 技术 做介绍&#xff1b; 2&#xff09;最小生成树是对无向图而言的&#xff1a;一个无向图G 的最小生成树是一个连通图…

Spring boot(七):Spring boot+ mybatis 多数据源最简解决方案

多数据源一般解决哪些问题&#xff1f;主从模式或者业务比较复杂需要连接不同的分库来支持业务。 直接上代码。 配置文件 pom包依赖&#xff0c;该依赖的依赖。主要是数据库这边的配置&#xff1a; mybatis.config-locationsclasspath:mybatis/mybatis-config.xmlspring.da…

Java:关于main方法的10道面试题

转载自 Java&#xff1a;关于main方法的10道面试题 1.main方法是做什么用的&#xff1f; 2.不用main方法如何运行一个类&#xff1f; 3.main方法如何传递参数&#xff1f;传递参数的类型是什么&#xff1f;能不能改变该参数类型&#xff1f; 4.main方法为什么是静态的&#xff…

ReviewForJob——深度优先搜索的应用

【0】README 1&#xff09;本文旨在 介绍 ReviewForJob——深度优先搜索的应用 及其 源码实现 &#xff1b; 2&#xff09;搜索树的技术分为广度优先搜索 和 深度优先搜索&#xff1a;而广度优先搜索&#xff0c;我们前面利用 广度优先搜索计算无权最短路径已经做过分析了&am…

Spring boot(八):RabbitMQ详解

RabbitMQ介绍 RabbitMQ既一个消息队列&#xff0c;主要用来实现应用程序的异步和解耦&#xff0c;同时也能起到消息缓冲&#xff0c;消息分发的作用。 消息中间件在互联网公司的使用中越来越多。消息中间件最主要的作用是解耦&#xff0c;中间件最标准的用法师生产者生产消息传…

关于Jvm知识看这一篇就够了

转载自 关于Jvm知识看这一篇就够了2016年左右的时候读了周志明《深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践》&#xff0c;读完之后受益匪浅&#xff0c;让我对Java虚拟机有了一个完整的认识&#xff0c;这是Jvm书籍中最好的读物之一。后来结合实际工作中遇到的问题…

ReviewForJob——算法设计技巧(贪婪算法+分治算法+动态规划)

【0】README 1&#xff09;本文旨在介绍算法设计技巧包括 贪婪算法、分治算法、动态规划 以及相关的荔枝等&#xff1b; 【1】贪婪算法 1&#xff09;intro&#xff1a; 贪婪算法是分阶段进行的&#xff0c;在每个阶段&#xff0c;可以认为所做的决定是最好的&#xff0c;而…

Spring boot(九):定时任务

在我们的项目开发过程中&#xff0c;进场需要定时任务来帮助我们做一些内容&#xff0c;springboot默认已经帮我们实行了&#xff0c;只要天剑相应的注解就可以实现。 1、pom包配置 pom包里面只需要引入springboot starter包即可 <dependencies><dependency><…

jvm系列(一):java类的加载机制

转载自 jvm系列(一):java类的加载机制1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内&#xff0c;然后在堆区创建一个 java.lang.Class对象&#xff0c;用来封装类在方法区内的数据结构。类的加载的最…

Springboot(十):邮件服务

发送邮件应该是网站的必备功能之一&#xff0c;什么注册验证&#xff0c;忘记密码或者是给用户发送营销信息。最早期的时候我们会使用javaMail相关api来写邮件相关代码&#xff0c;后来spring退出了javaMailSender 更加简化了邮件发送的过程&#xff0c;在之后springboot 对此进…

How to install plugin for Eclipse from .zip

these contents are reshiped from 如何在eclipse中安装.zip插件 1.make sure your .zip file is an valid Eclipse Plugin Note: that means: your .zip file contains folders features and plugins, like this:for new version Eclipse Plugin, it may also include anothe…

jvm系列(二):JVM内存结构

转载自 jvm系列(二):JVM内存结构所有的Java开发人员可能会遇到这样的困惑&#xff1f;我该为堆内存设置多大空间呢&#xff1f;OutOfMemoryError的异常到底涉及到运行时数据的哪块区域&#xff1f;该怎么解决呢&#xff1f;其实如果你经常解决服务器性能问题&#xff0c;那么这…

jvm系列(三):GC算法 垃圾收集器

转载自 jvm系列(三):GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”&#xff0c;它诞生于1960年 MIT 的 Lisp 语言&#xff0c;经过半个多世纪&#xff0c;目前已经十分成熟了。 jvm 中&#xff0c;程序计数器、虚拟机栈、本地方法栈都是随线程而生随线…

Spring boot(十二):Spring boot 如何测试、打包、部署

博文引用&#xff1a;springboot(十二)&#xff1a;springboot如何测试打包部署 开发阶段 单元测试 Spring boot对单元测试的支持已经很完善了。 1 在pom包中添加Spring-boot-starter-test包引用 <dependency><groupId>org.springframework.boot</groupId&g…

Java虚拟机详解----常用JVM配置参数

【声明】 欢迎转载&#xff0c;但请保留文章原始出处→_→ 生命壹号&#xff1a;http://www.cnblogs.com/smyhvae/ 文章来源&#xff1a;http://www.cnblogs.com/smyhvae/p/4736162.html 联系方式&#xff1a;smyhvae163.com 本文主要内容&#xff1a; Trace跟踪参数堆的…

jvm系列(四):jvm调优-命令篇

转载自 jvm系列(四):jvm调优-命令篇 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题&#xff01;虽然jvm调优成熟的工具已经有很多&#xff1a;jconsole、大名鼎鼎的VisualVM&#xff0c;IBM的Memory Analyzer等等&#xff0c;但是在生产环境出…

Sprng boot(十三):Spring boot 小技巧

初始化数据 使用jpa 在使用Spring boot jpa的情况下设置 spring.jpa.hibernate.ddl-auto 的属性为 create 或 create-drop &#xff0c;Spring boot启动时默认会扫描classpath下面&#xff08;项目一般是resources目录&#xff09;是否有import.sql&#xff0c;如果有机会执行…

滴滴2017在线笔试有感

呵呵 刚才参加完了 滴滴2017的在线笔试。 又一次被虐。。班上很多人都在耍算法&#xff0c;这样算法 那样算法。其实今天看他的 题目 也就是 数据结构的基础知识&#xff0c; 没有多高深的算法。。当然这是一个小生的 匹夫之言&#xff1b; 编程第一题&#xff1a; 求最大子序列…