数据结构基础

一.堆栈

      堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。要点:

堆:顺序随意 ;栈:后进先出(Last-In/First-Out)

 

题目:实现一个栈操作,将1`12月的英文单词压入栈中,然后将其取出,使用Java代码实现.

 

public class Stacks {
	static String[] months = { "A", "B", "C", "D", "E", "F", "G" };

	public static void main(String[] args) {
		Stack stack = new Stack<>();// 新建一个栈
		for (int i = 0; i < months.length; i++) {
			stack.push(months[i]);// 将元素一个个放进去
		}
		System.out.println(stack);
		while (!stack.empty()) {
			System.out.println(stack.pop());//将元素拿出来出来
		}
	}
}

 

二.链表与哈希表

存储结构分为以下几种:

 

(1)随机存取

 即可以随机存取任意一个元素,可以通过下标直接存取任何一个元素如数组等:又如内存,可以通过地址访问任意一个元素

(2)顺序存储

就是只能从头到尾逐个访问.像连表这种结构.不能够直接通过下标访问,必须从表头开始,向后逐个搜索,就是顺序存储.这和磁带一样,想听后边的歌曲,就得把前面的磁带转过去,按照顺序来

(3)索引存取

是指为某个关键字建立索引表,从所有的表中得到地址,再直接访问.索引存取多用于数据管理过程中

(4)散列存储

也称为hash存储

这个可能比较陌生,那么来通俗理解下

 

设要存储对象的个数为num, 那么我们就用len个内存单元来存储它们(len>=num); 以每个对象ki的关键字为自变量,用一个函数h(ki)来映射出ki的内存地址,也就是ki的下标,将ki对象的元素内容全部存入这个地址中就行了。这个就是Hash的基本思路。

Hash为什么这么想呢?换言之,为什么要用一个函数来映射出它们的地址单元呢?

This is a good question.明白了这个问题,Hash不再是问题。下面我就通俗易懂地向你来解答一下这个问题。

现在我要存储4个元素 13 7 14 11

显然,我们可以用数组来存。也就是:a[1] = 13; a[2] = 7; a[3] = 14; a[4] = 11;

当然,我们也可以用Hash来存。下面给出一个简单的Hash存储:

先来确定那个函数。我们就用h(ki) = ki%5;(这个函数不用纠结,我们现在的目的是了解为什么要有这么一个函数)。

对于第一个元素 h(13) = 13%5 = 3; 也就是说13的下标为3;即Hash[3] = 13;

对于第二个元素 h(7) = 7 % 5 = 2; 也就是说7的下标为2; 即Hash[2] = 7;

同理,Hash[4] = 14; Hash[1] = 11;

好了,存现在是存好了。但是,这并没有体现出Hash的妙处,也没有回答刚才的问题。下面就来揭开它神秘的面纱吧。

现在我要你查找11这个元素是否存在。你会怎么做呢?当然,对于数组来说,那是相当的简单,一个for循环就可以了。

也就是说我们要找4次。

下面我们来用Hash找一下。

首先,我们将要找的元素11代入刚才的函数中来映射出它所在的地址单元。也就是h(11) = 11%5 = 1 了。下面我们来比较一下Hash[1]?=11, 这个问题就很简单了。也就是说我们就找了1次。这个就是Hash的妙处了。至此,刚才的问题也就得到了解答。至此,你也就彻底的明白了Hash了。

 

题目:有一千万条重复的短信,以文本形式保存,一行一条,也有重复.请用5分钟时间找出重复出现最多的前十条短信

分析:

刚开始肯定会冒出导入数据库,然后用select语句进行查找.但是你再仔细想想这个可是一千万条数据,全部导入后都不止5分钟了,你还要建立索引啥的.

可以采用内存映射办法.首先,一千万条短信长度将不会超过1内存空间,使用内存映射文件比较合适.可以一次映射(如果有更大的数据量,可以采用分段映射),由于不需要频繁使用文件I/O和频繁分配内存大小,这将大大提高了数据的加载速度.其次,对每条短信的第i(i从0到70)个字母按照ASCII码进行分组,也就是创建树.i是树的深度也是短信的第i个字母

 

三,树

题目:前序遍历二叉树值为abcdefg,下面哪一个不可能是中序遍历?

A.abcdefg B.gfedcba C.bcdefga D.bceadfg

 

二叉树遍历原则,前序遍历是根左右,中序遍历是左根右,后序遍历是左右根。

题目既然说前序遍历abcdefg,所以根为a,D中bce在左,dfg在右,显然与先序遍历冲突

 

 

二叉树遍历分析

  简单二叉树遍历,可分为:先序,中序,后序。

  在此分别总结先序,中序,后序的结点输出顺序。

  先序: 1.访问根结点

    2.访问左子树

    3.访问右子树

 

先序较简单,不予以即系解释。

  中序:1.访问左子树

     2.访问根结点

       3.访问右子树

    原则:访问左子树。【先访问左子树中的左子树,再访问左子树中的右子树。】直到访问到叶子结点后输出。

       输出根。

         访问右子树。【先访问右子树中的左子树,再访问右子树中的右子树。】直到访问到叶子结点后输出。

具体步骤如下:

  A作为根。从A开始,先访问A的左子树。即

在看B的左子树,D。则输出D。B无左子树。访问完B的左子树。然后访问B。输出B。再看B的右子树。F有左子树E,则输出E。返回输出F。A的左子树全部输出完,再返回A,输出A。

  

同理,看A的右子树。。输出顺序为G,H,C,I。

 

所以,中序遍历输出的结果为:(D B E F)A(G H C I).

 

  后序:1.访问左子树

     2.访问右子树

          3.访问根

     原则:访问左子树。【先访问左子树中的左子树,再访问左子树中的右子树】。直到访问到叶子结点后输出。

        访问右子树。【先访问右子树中的左子树,再访问右子树中的右子树】。直到访问到叶子结点后输出。

        再返回访问根,并输出。

具体步骤:

  先访问A的左子树。再访问左子树中的左子树。【即:A的左子树为B,再访问B的左子树D。D没有左右子树,输出D。】,然后访问左子树中的右子树。【即:访问B的右子树F,F还有左子树,再访问F的左子树E,E没有左右子树。输出E。再输出F,再输出B。】。

  然后访问A的右子树。再访问右子树中的左子树。【即:A的右子树为C,再访问C的左子树G。G还有右子树H,输出H。再输出G,再输出G】,然后访问右子树中的右子树。【即:访问C的右子树I,I没有左右子树,输出I。在输出C。再输出A。】。

  所以,后序遍历输出结果为:(D E F B)(H G I C)A

 

一个包含n个节点的四叉树,每一个结点都有4个指向该节点的指针,这个四叉树有_个空指针

分析:n个节点有n-1个非空指针,其余为空指针、4*n-(n-1)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值