二叉堆的java代码实现 c++二叉堆

java实现对树形结构(文件夹式)数据数组进行排序这个问题本质上就是个数据结构的问题,所谓排序和查找效率依赖的是算法和数据结构的配合,你现在定下了链表(没有具体说明的话 , 这里应该指的是单向链表吧)、数组和二叉树,这几个之中,那排序和查找的数据就看用什么算法和相应的数据结构配合了~~~
排序算法中,快速排序是最快的 , 比较适合用链表来处理,但是链表的查找是比较慢的(双向链表的话可以加快查找速度) 。
数组排序会比较慢,不是算法的问题,而是数组的调整因为需要位移,但是数组一旦排号顺序后,查找是很快的——折半查找 。
二叉数较为平局 , 排序可以采用堆排序,查找可以建二叉排序树来找(用B 或B-树的话可以更快) 。
个人看法,不一定对,欢迎拍砖,具体代码知道算法了就自己上网找吧 。
Java中实现栈时的问题----------Java高手请进p2=p1不是Point对象赋值,而是引用赋值 。这和C不一样 。
在java里边,p1、p2、point和temp都是引用,而不是对象本身 , 引用就象C的指针 。上面的程序中,p2=p1的结果是 , p2指向的对象和p1相同,他们都指向了p1=new Point()语句创建的对象 。而Point p2=new Point(); 创建的对象,因为p2不再引用它而变成垃圾,java会自动删除 。
java的引用赋值就象C的指针赋值,就类似C程序:
Point * p1=new Point();
Point * p2=new Point();
p2=p1;
所以你上面的程序也有这个问题,temp=point;其实没什么用,效果把Point temp=new mypoint(); 创建的对象删除了,被压栈的对象还是point , 所以去掉这两句,效果完全一样 。
如果你想复制一个新对象压栈,应该用java的clone方法 ,
temp=point.clone();
不过Point必须实现Clonable接口,并且正确实现它 。
java如何创建一颗二叉树计算机科学中,二叉树是每个结点最多有两个子树二叉堆的java代码实现的有序树 。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree) 。二叉树常被用作二叉查找树和二叉堆或是二叉排序树 。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒 。二叉树的第i层至多有2的 i -1次方个结点二叉堆的java代码实现;深度为k的二叉树至多有2^(k) -1个结点二叉堆的java代码实现;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0 , 度为2的结点数为n2,则n0 = n21 。
树是由一个或多个结点组成的有限集合,其中二叉堆的java代码实现:
⒈必有一个特定的称为根(ROOT)的结点;
二叉树
⒉剩下的结点被分成n=0个互不相交的集合T1、T2、......Tn , 而且,这些集合的每一个又都是树 。树T1、T2、......Tn被称作根的子树(Subtree) 。
树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树
1.树的度——也即是宽度,简单地说 , 就是结点的分支数 。以组成该树各结点中最大的度作为该树的度 , 如上图的树,其度为2;树中度为零的结点称为叶结点或终端结点 。树中度不为零的结点称为分枝结点或非终端结点 。除根结点外的分枝结点统称为内部结点 。
2.树的深度——组成该树各结点的最大层次 。
3.森林——指若干棵互不相交的树的集合,如上图,去掉根结点A , 其原来的二棵子树T1、T2、T3的集合{T1,T2,T3}就为森林;
4.有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树 , 否则称为无序树 。
树的表示
树的表示方法有许多,常用的方法是用括号:先将根结点放入一对圆括号中,然后把它的子树由左至右的顺序放入括号中 , 而对子树也采用同样的方法处理;同层子树与它的根结点用圆括号括起来,同层子树之间用逗号隔开,最后用闭括号括起来 。如右图可写成如下形式:
二叉树
(a( b(d,e), c( f(,g(h,i) ),)))
第一排01第二排02 03,以此类推,怎么用代码实现数据排列效果选择排序是常用内部排序二叉堆的java代码实现的一种二叉堆的java代码实现,常见的实现算法有直接选择排序算法和堆排序算法二叉堆的java代码实现 , 选择排序的基本思想是每次从待排数据中选择第n小的数据放到排序列表的第n个位置 , 假如共有N个数据待排,那么经过N-1次排序后,待排数据就已经按照从小到大的顺序排列二叉堆的java代码实现了 。
直接选择排序算法的思想比较简单:(假设数据放在一个数组a中,且数组的长度是N)
1:从a[0]-a[N-1]中选出最小的数据,然后与a[0]交换位置
2:从a[1]-a[N-1]中选出最小的数据 , 然后与a[1]交换位置(第1步结束后a[0]就是N个数的最小值)
3:从a[2]-a[N-1]中选出最小的数据,然后与a[2]交换位置(第2步结束后a[1]就是N-1个数的最小值)
以此类推,N-1次排序后,待排数据就已经按照从小到大的顺序排列了 。
直接选择排序的java实现如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void selectionSort(int[] elements){
for(int i = 0; ielements.length-1;i){
int k = i;
for(int j = i; jelements.length;j){
if(elements[k]elements[j]){
k = j;
}
}
if(k != i){//交换元素
int temp = elements[i];
elements[i] = elements[k];
elements[k] = temp;
}
}
}
直接选择排序算法的思路很清晰,实现起来也比较简单,但是效率不是很高(O(n*n)) 。
堆排序算法和直接选择排序算法最大的不同在于,堆排序算法充分利用大顶堆和完全二叉树的性质,保留每次排序后的结构,同时由于每次比较只是比较根节点和它的子节点,因此大大降低了比较的次数和交换的次数,从而提高效率,堆排序算法的时间复杂度是O(nlogn,以2为底) 。
堆排序算法的思想是:(假设数据放在一个数组a中,且数组的长度是N)
1:以数组a为数据,建立一个大顶堆(这样对于二叉树的每个节点,根节点总是比子节点大,其实没必要要求二叉树的每个子树也是大顶堆)
2:交换大顶堆的根节点和数组a中的最后一个节点(最后一个节点不在参与后边的工作)
重复上边的工作 , 经过N-1次后 , 数组a已经排好序 。
其二叉堆的java代码实现他的我不太会
java面试题 很急 谢谢2, 归并排序(merge sort)体现了分治的思想,即将一个待排序数组分为两部分,对这两个部分进行归并排序,排序后,再对两个已经排序好的数组进行合并 。这种思想可以用递归方式很容易实现 。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n) 。
实现代码如下:
#include stdio.h
#include "common.h"
void merge(int data[], int p, int q, int r)
{
int i, j, k, n1, n2;
n1 = q - p1;
n2 = r - q;
int L[n1];
int R[n2];
for(i = 0, k = p; in1; i, k)
L[i] = data[k];
for(i = 0, k = q1; in2; i, k)
R[i] = data[k];
for(k = p, i = 0, j = 0; in1jn2; k)
{
if(L[i]R[j])
{
data[k] = L[i];
i;
}
else
{
data[k] = R[j];
j;
}
}
if(in1)
{
for(j = i; jn1; j, k)
data[k] = L[j];
}
if(jn2)
{
for(i = j; in2; i, k)
data[k] = R[i];
}
}
void merge_sort(int data[], int p, int r)
{
if(pr)
{
int q = (pr) / 2;
merge_sort(data, p, q);
merge_sort(data, q1, r);
merge(data, p, q, r);
}
}
void test_merge_sort()
{
int data[] = {44, 12, 145, -123, -1, 0, 121};
printf("-------------------------------merge sort----------------------------\n");
out_int_array(data, 7);
merge_sort(data, 0, 6);
out_int_array(data, 7);
}
int main()
{
test_merge_sort();
return 0;
}
4.对于有n个结点的线性表(e0,e1,…,en-1),将结点中某些数据项的值按递增或递减的次序,重新排列线性表结点的过程 , 称为排序 。排序时参照的数据项称为排序码,通常选择结点的键值作为排序码 。
若线性表中排序码相等的结点经某种排序方法进行排序后,仍能保持它们在排序之前的相对次序,称这种排序方法是稳定的;否则,称这种排序方法是不稳定的 。
在排序过程中,线性表的全部结点都在内存,并在内存中调整它们在线性表中的存储顺序,称为内排序 。在排序过程中,线性表只有部分结点被调入内存,并借助内存调整结点在外存中的存放顺序的排序方法成为外排序 。
下面通过一个表格简单介绍几种常见的内排序方法,以及比较一下它们之间的性能特点 。
排序方法
简介
平均时间
最坏情况
辅助存储
是否稳定
简单排序
选择排序
反复从还未排好序的那部分线性表中选出键值最小的结点,并按从线性表中选出的顺序排列结点,重新组成线性表 。直至未排序的那部分为空,则重新形成的线性表是一个有序的线性表 。
O()
O()
O(1)
不稳定
直接插入排序
假设线性表的前面I个结点序列e0 , e1,…,en-1是已排序的 。对结点在这有序结点ei序列中找插入位置,并将ei插入,而使i 1个结点序列e0 , e1,… , ei也变成排序的 。依次对i=1,2,… , n-1分别执行这样的插入步骤,最终实现线性表的排序 。
O()
O()
O(1)
稳定
冒泡排序
对当前还未排好序的范围内的全部结点,自上而下对相邻的两个结点依次进行比较和调整,让键值大的结点往下沉,键值小的结点往上冒 。即 , 每当两相邻比较后发现它们的排列顺序与排序要求相反时,就将它们互换 。
O()
O()
O(1)
稳定
希尔排序
对直接插入排序一种改进,又称“缩小增量排序” 。先将整个待排序列分割成为若干子序列分别进行直接插入排序 , 待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序 。
knlnn
O()
O(logn)
不稳定
快速排序
对冒泡排序的一种本质的改进 。通过一趟扫视后,使待排序序列的长度能大幅度的减少 。在一趟扫视后,使某个结点移到中间的正确位置,并使在它左边序列的结点的键值都比它的小,而它右边序列的结点的键值都不比它的小 。称这样一次扫视为“划分” 。每次划分使一个长序列变成两个新的较小子序列,对这两个小的子序列分别作同样的划分,直至新的子序列的长度为1使才不再划分 。当所有子序列长度都为1时,序列已是排好序的了 。
O(nlogn)
O()
O(logn)
不稳定
堆排序
一种树形选择排序 , 是对直接选择排序的有效改进 。一个堆是这样一棵顺序存储的二叉树,它的所有父结点(e[i])的键值均不小于它的左子结点(e[2*i 1])和右子结点(e[2*i 2])的键值 。初始时,若把待排序序列的n个结点看作是一棵顺序存储的二叉树 , 调整它们的存储顺序,使之成为一个堆 , 这时堆的根结点键值是最大者 。然后将根结点与堆的最后一个结点交换,并对少了一个结点后的n-1结点重新作调整 , 使之再次成为堆 。这样,在根结点得到结点序列键值次最大值 。依次类推 , 直到只有两个结点的堆,并对它们作交换,最后得到有序的n个结点序列 。
O(nlogn)
O(nlogn)
O(1)
不稳定
归并排序
将两个或两个以上的有序子表合并成一个新的有序表 。对于两个有序子表合并一个有序表的两路合并排序来说,初始时,把含n个结点的待排序序列看作有n个长度都为1的有序子表所组成,将它们依次两两合并得到长度为2的若干有序子表,再对它们作两两合并……直到得到长度为n的有序表,排序即告完成 。
O(nlogn)
O(nlogn)
O(n)
稳定
后面根据各种排序算法,给出了C语言的实现,大家在复习的时候可以做下参考 。
u选择排序
voidss_sort(inte[],intn)
{inti,j,k,t;
for(i=0;in-1;i){
for(k=i,j=i 1;jn;j)
if(e[k]e[j])k=j;
if(k!=i){
t=e[i];e[i]=e[k];e[k]=t;
}
}
}
u直接插入排序
voidsi_sort(inte[],intn)
{inti,j,t;
for(i=0;in;i){
for(t=e[i],j=i-1;j=0te[j];j--)
e[j 1]=e[j];
e[j 1]=t;
}
}
u冒泡排序
voidsb_sort(inte[],intn)
{intj,p,h,t;
for(h=n-1;h0;h=p){
for(p=j=0;jh;j)
if(e[j]e[j 1]){
t=e[j];e[j]=e[j 1];e[j 1]=t;
p=j;
}
}
}
u希尔排序
voidshell(inte[],intn)
{intj,k,h,y;
for(h=n/2;h0;h=h/2)
for(j=h;jn;j){
y=e[j];
for(k=j-h;k0ye[k];k-=h)
e[k h]=e[k];
e[k h]=y;
}
}
u堆排序
voidsift(e,n,s)
inte[];
intn;
ints;
{intt,k,j;
t=e[s];
k=s;j=2*k 1;
while(jn){
if(jn-1e[j]e[j 1])
j;
if(te[j]){
e[k]=e[j];
k=j;
j=2*k 1;
}elsebreak;
}
e[k]=t;
}
voidheapsorp(inte[],intn)
{inti,k,t;
for(i=n/2-1;i=0;i--)
sift(e,n,i);
for(k=n-1;k=1;k--){
t=e[0];e[0]=e[k];e[k]=t;
sift(e,k,0);
}
}
u快速排序
voidr_quick(inte[],intlow,inthigh)
{inti,j,t;
if(lowhigh){
i=low;j=high;t=e[low];
while(ij){
while(ije[j]t)j--;
if(ij)e[I]=e[j];
while(ije[i]=t)i;
if(Ij)e[j--]=e[i];
}
e[i]=t;
r_quick(e,low,i-1);
r_quick(w,i 1,high);
}
}
另外,外排序是对大型文件的排序,待排序的记录存储在外存中,在排序过程中 , 内存只存储文件的一部分记录 , 整个排序过程需进行多次的内外存间的交换 。
***查找
查找就是在按某种数据结构形式存储的数据集合中 , 找出满足指定条件的结点 。
按查找的条件分类 , 有按结点的关键码查找、关键码以外的其他数据项查找或其他数据项的组合查找等 。按查找数据在内存或外存,分内存查找和外存查找 。按查找目的,查找如果只是为了确定指定条件的结点存在与否,成为静态查找;查找是为确定结点的插入位置或为了删除找到的结点,称为动态查找 。
这里简单介绍几种常见的查找方法 。
u顺序存储线性表的查找
这是最常见的查找方式 。结点集合按线性表组织,采用顺序存储方式 , 结点只含关键码 , 并且是整数 。如果线性表无序 , 则采用顺序查找,即从线性表的一端开始逐一查找 。而如果线性表有序,则可以使用顺序查找、二分法查找或插值查找 。
u分块查找
分块查找的过程分两步,先用二分法在索引表中查索引项,确定要查的结点在哪一块 。然后,再在相应块内顺序查找 。
u链接存储线性表的查找
对于链接存储线性表的查找只能从链表的首结点开始顺序查找 。同样对于无序的链表和有序的链表查找方法不同 。
u散列表的查找
散列表又称杂凑表,是一种非常实用的查找技术 。它的原理是在结点的存储位置和它的关键码间建立一个确定的关系,从而让查找码直接利用这个关系确定结点的位置 。其技术的关键在于解决两个问题 。
I.找一个好的散列函数
这两道题代码怎么写java?创建一个名字为“ReportCard”的类二叉堆的java代码实现,然后用下边的内容全部替换掉,二叉堆的java代码实现你会成为全班最亮的仔 。
import java.util.HashMap;
/**
* 学生成绩单
*/
public class ReportCard {
public static void main(String[] args) {
ReportCard reportCard = new ReportCard("张三", "070602213");
reportCard.set("语文", 80.0);
reportCard.set("数学", 59.5);
reportCard.set("英语", 66.0);
reportCard.set("java", 80, 99.0);
reportCard.set("数据库", 80, 66.0);
reportCard.set("毛概", null);
System.out.println(reportCard.getStudentName()"语文分数:"reportCard.get("语文"));
System.out.println(reportCard.getStudentName()"数学考核结果:"(reportCard.isPassed("数学") ? "合格" : "不合格"));
System.out.println(reportCard.getStudentName()"期末是否挂科二叉堆的java代码实现:"(reportCard.isAllPassed() ? "否" : "是"));
}
// 学生姓名
private String studentName;
// 学生学号
private String studentNumber;
// 成绩单
private HashMapString, CourseResult cards = new HashMap();
public ReportCard() {
}
public ReportCard(String studentName, String studentNumber) {
this.studentName = studentName;
this.studentNumber = studentNumber;
}
public Double get(String courseName){
CourseResult courseResult = cards.get(courseName);
return courseResult == null ? Double.NaN : courseResult.getStudentScore();
}
public void set(String courseName, Double studentScore){
CourseResult courseResult = new CourseResult(courseName, studentScore);
cards.put(courseName, courseResult);
}
public void set(String courseName, double passMark, Double studentScore){
CourseResult courseResult = new CourseResult(courseName, passMark, studentScore);
cards.put(courseName, courseResult);
}
public boolean isPassed(String courseName){
return cards.get(courseName).isPassed();
}
public boolean isAllPassed(){
for(CourseResult cr : cards.values()){
if ( ! cr.isPassed()) {
return false;
}
}
return true;
}
public String getStudentName() {
return studentName;
}
public String getStudentNumber() {
return studentNumber;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public void setStudentNumber(String studentNumber) {
this.studentNumber = studentNumber;
}
/**
* 课程
*/
class Course{
// 课程名称
protected String courseName;
// 及格分
protected double passMark = 60;
public Course(String courseName, Double passMark) {
this.courseName = courseName;
if ( passMark != null) {
this.passMark = passMark;
}
}
}
/**
* 课程成绩
*/
class CourseResult extends Course{
// 学生成绩
private Double studentScore;
public CourseResult(String courseName, Double studentScore) {
this(courseName, null, studentScore);
}
public CourseResult(String courseName, Double passMark, Double studentScore) {
super(courseName, passMark);
this.studentScore = studentScore == null ? Double.NaN : studentScore;
}
public boolean isPassed(){
return studentScore = passMark;
}
public String getCourseName() {
return courseName;
}
public double getPassMark() {
return passMark;
}
public Double getStudentScore() {
return studentScore;
}
}
【二叉堆的java代码实现 c 二叉堆】关于二叉堆的java代码实现和c二叉堆的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读