`
独爱Java
  • 浏览: 32009 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

数据结构学习笔记之一

阅读更多
数据结构学习笔记之一
注:参考书籍为数据结构-严蔚敏编著  2011/11/28 下午


第一章:数据结构概述
一、什么是数据结构
1、作者开篇谈到:
   一般来说解决一个具体的问题时,大致需要经过下列几个步骤:首先要从具体的问题抽象出一个适当的数学模型,然后设计一个解此数学模型的算法,最后编写出程序代码,进行测试、调整直至得到最终的解决方案。
总结为:现实中具体的问题—>数学模型—>算法程序—>解决方案
动作为:抽象提取、设计编码、测试调整
2、数学角度阐述:
   寻求数学模型的实质是分析问题,从中提取操作的对象,并找出这些操作对象之间含有的关系,然后用数学的语言加以描述。
3、定义数据结构:
   描述这类非数值计算问题的数学模型不再是数学方程,而是诸如表、树和图之类的数据结构,因此,简单来说,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间关系和操作等的学科,用一句话来说就是,数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
   研究对象:1、集合2、线性结构3、树形结构4、图状结构(网状结构)
   结构分类:1、数据的逻辑结构2、数据的物理结构(存储结构)
   关系表示:1、顺序映像2、非顺序映像,两者分别对应为顺序存储结构、链式存储结构
二、算法和算法分析
   1、算法的五个特性:有穷性、确定性、可行性、输入和输出
   2、算法设计的要求:正确性、可读性、健壮性以及效率与低存储量需求
   3、算法的度量:时间复杂度和空间复杂度
   总结:编写代码设计算法时候首先先考虑算法的正确性,确保程序能够满足要求,在正确性的前提下再进一步考虑算法的可读性、健壮性、拓展性以及算法的效率等。

第二章:线性表
一、线性表的定义
   线性结构的特点是:在数据元素的非空有限集中(1)存在唯一的一个被称做“第一个”的数据元素;(2)存在唯一的一个被称做“最后一个”的数据元素;(3)除第一个之外,集合中每个数据元素均只有一个前驱;(4)除最后一个元素之外,集合中每个数据元素均只有一个后继。
   线性表是最常用并且最简单的一种数据结构,简单来说,一个线性表是n个数据元素的有限序列。至于每个数据元素的具体含义,在不同的情况下各不相同,既可以是一个数也可以是一个符号等等。
二、线性表的操作
   线性表是一个相当灵活的数据结构,它的长度可根据需要增长或者缩短,即对线性表的数据元素不但可以进行访问,还可以进行插入和删除等操作。线性表存储方式有两种,顺序存储和链式存储,下面通过代码进行简单模拟操作。
三、代码模拟简单实现
   线性表求交、求并、线性表查找、插入、删除元素等操作。
1、顺序存储方式:
   参加具体代码模拟实现、功能性上模拟、算法效率另当别论了。
2、链表相关问题:
   单循环链表、判断链表是否有环、判断两个链表是否相交、删除某个特定的链表结点等操作。
线性表模拟接口-实现代码如下:
import java.util.List;

/**
 * @author Administrator
 * 
 * @description 线性表模拟测试接口
 * @history
 */
public interface ListTest {
	
	/**
	 *@description 求两个线性表集合的交集
	 *@return 返回两个集合的交集
	 */
	List<Integer> jiaoJi(List<Integer> aList,List<Integer> bList);
	
	/**
	 *@description 求两个线性表集合的并集
	 *@return 返回合并后的集合
	 */
	List<Integer> bingJi(List<Integer> aList,List<Integer> bList);
	
	/**
	 *@description 在某个index后插入一个元素
	 *@return 插入成功返回true反之返回false
	 */
	boolean insert(List<Integer> list,int index,int value);
	
	/**
	 *  
	 *@description 查找某个元素是否存在
	 *@return 查找成功返回true反之返回false
	 */
	boolean findByValue(List<Integer> list,Integer value);
	
	/**
	 *@description 根据索引index删除某个位置上的元素
	 *@return 删除成功返回true反之返回false
	 */
	boolean deleteByIndex(List<Integer> list,int index);
	
// boolean isCircle(List<Integer> list);
// 判断单链表是否有环方法主要有两种
// 方法一、哈希,方法二、快慢指针
	
// boolean isXiangjiao(List<Integer> aList,List<Integer> bList);
// 判断两个单链表是否相交方法比较多
// 暴力处理、哈希、指针遍历(将其中一个尾指向头,从另外一个头指针开始遍历看是否能到达另外一个头部)等
// 如果要定位出相交点的位置,哈希处理方式在时间上有优势但是空间上是劣势-参考自编程之美
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Administrator
 * 
 * @description 操作实现类,简单功能模拟实现而已
 * @history
 */
public class ListTestImpl implements ListTest {

	public List<Integer> jiaoJi(List<Integer> aList, List<Integer> bList) {
		// 采用最简单的方式实现,暂不考虑效率问题
		List<Integer> cList = new ArrayList<Integer>();
		int aLength = aList.size();
		int bLength = bList.size();
		Integer temp = null; //临时比较的值
		
		for (int i = 0; i < aLength; i++) {
			temp = aList.get(i);
			int j = 0; 
			for (; j < bLength; j++) {
				if (temp.equals(bList.get(j)))
					break; //循环遍历到相同元素后跳出当前循环
			}
			
			//将满足条件的元素放置在新的list中
			if (j < bLength) cList.add(temp);
		}
		return cList;
	}

	public List<Integer> bingJi(List<Integer> aList, List<Integer> bList) {
		// 因为是线性表的并集,元素可以重复的,这个和数学上的并集不同
		// 暂时不考虑效率性能,采用方法为先对list排序好然后再求并集
		List<Integer> cList = new ArrayList<Integer>();
		List<Integer> list1 = aList;
		List<Integer> list2 = bList;
		
		// 对两个集合进行排序操作
		Collections.sort(list1);
		Collections.sort(list2);
		
		int aLength = list1.size();
		int bLength = list2.size();
		int i=0,j=0; //下标标记值
		
		while (i < aLength && j < bLength) {
			if (list1.get(i) <= list2.get(j)) {
				cList.add(list1.get(i));
				i++; 
			} else{
				cList.add(list2.get(j));
				j++;
			}
		}
		while(i< aLength){
			cList.add(list1.get(i));
			i++;
		}
		while(j<bLength){
			cList.add(list2.get(j));
			j++;
		}
		return cList;
	}

	public boolean insert(List<Integer> list, int index, int value) {
		// 直接采用ArrayList实现代码模拟实现了
		// 顺序存储方式需要在某个index后添加元素需要遍历、移动、插入元素等操作
		int length = list.size();
		if (index >= length)
			return false; //下标越界
		
		// 采用转换方法或者直接采用自动装箱
		list.add(index,Integer.valueOf(value));
		return true;
	}

	public boolean findByValue(List<Integer> list, Integer value) {
		// 遍历一遍集合即可查询是否存在某个元素
		int length = list.size();
		int i = 0;
		for (; i < length; i++) {
			if (list.get(i).equals(value)) {
				break;
			}
		}
		if(i == length) return false;
		else return true;

	  // 如果是排序好的则不需要直接遍历集合一遍,采用二分查找从而提高效率
	  // 二分法代码如下
             /*int low = 0;
		int high = list.size();
		int middle = (low+high)/2;	
		while (low <= high) {
			if (list.get(middle).equals(value) || list.get(low).equals(value)
					|| list.get(high).equals(value)) {
				return true; // 存在该元素,返回true			
			} else if (list.get(middle) > value) {
				low++;
				high = middle - 1;
				middle = (low + high) / 2;	
            } else {
				high--;
				low = middle + 1;
				middle = (low + high) / 2;
			}
		}
		return false;*/
		
		
// 如果再次改变需求,集合中元素排序好并且有重复的数字,如何最好找出某个元素第一次出现的index
// 对上面二分法进行改造处理即可
		
	}

	public boolean deleteByIndex(List<Integer> list, int index) {
		// 直接采用底层实现处理,如果要具体模拟需要遍历、删除并且移动元素等操作
		int length = list.size();
		if(index >= length) return false;
		else{
			list.remove(index);
			return true;
		}		
// 如果是链式存储方式删除某个结点改变下指向即可
// 如果删除某个没有源指向的结点,采用偷换结点的思路删除节点即可
	}

}

第三章:栈和队列
   栈和队列是两种重要的线性结构,从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表操作的子集,它们是操作受限制的线性表,因此可以称为限定性的数据结构。
一、栈的定义
   栈是限定在表尾进行插入或删除操作的线性表,栈的特定是先进后出。栈的存储方式有两种,一种是顺序栈另外一种是链式栈,下面只通过代码简单模拟栈的操作。
二、栈的应用
   栈的应用主要有数制转换、括号匹配的检验、迷宫问题求解以及表达式求值。另外栈递归实现的经典例子有八皇后问题、汉诺塔问题等。
三、队列的定义
   队列和栈有点不同,队列是一种先进先出得线性表,它只能够在表的一端进行插入另外一头进行删除操作。队列在程序设计中比较常见的例子是操作系统中的作业排队。双端队列、循环队列有时间再进一步演进,暂时先了解些基本概念。
  学习过程中代码如下:
/**
 * @author Administrator
 * 
 * @description 栈的简单模拟测试类
 * @history
 */
public class StackTest {

	/**
	 *@description 
	 *@param args
	 */
	public static void main(String[] args) {
		// 栈的底层实现是数组形式继承自Vector
		// public class Stack<E> extends Vector<E> {}
		
		Stack<String> stack = new Stack<String>();
		// 入栈操作
		stack.push("world");
		stack.push("hello");
		// 出栈操作
		while(!stack.empty()){
			// 栈的特点先进后出,输出hello world
			System.out.print(stack.pop()+" "); 
		}
		
		// 初步学习Stack类的源代码
		// Stack类的pop出栈方法
		/*public synchronized E pop(){ //同步方法处理
			E obj;  //采用了泛型
			int len = size(); //数组长度
			obj = peek(); //获取栈顶元素,对应数组尾部
			removeElementAt(len-1); //移除当前栈顶元素
			return obj; //返回移除的栈顶元素
		}*/
		
		// 移除方法removeElementAt学习
		/*public synchronized void removeElementAt(int index) { 
	    	modCount++; // 修改计数
	    	
	    	// 数组越界处理,对外抛出异常
	    	if (index >= elementCount) {
	    	    throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);
	    	}else if (index < 0) {
	    	    throw new ArrayIndexOutOfBoundsException(index);
	    	}
	    	
	    	// 计算当前index后面的元素个数
	    	int j = elementCount - index - 1; 
	    	if (j > 0) {
	    	    // 借助系统帮助类对数组进行重组
	    	    System.arraycopy(elementData, index + 1, elementData, index, j);
	    	}
	    	elementCount--; 
	    	elementData[elementCount] = null;// 赋值为null交给垃圾回收处理
	    }*/
		
	}

}

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author Administrator
 * 
 * @description 队列的简单测试代码
 * @history
 */
public class QueueTest {

	/**
	 *@description 
	 *@param args
	 */
	public static void main(String[] args) {
		// 采用LinkedList类进行简单模拟功能
		// public class LinkedList<E> implements Deque<E>{}
		// 队列接口继承自collection接口
		// public interface Queue<E> extends Collection<E> {}
		Queue<String> queue = new LinkedList<String>();
		
		// 入队列操作
		queue.add("hello");
		queue.add("world");
		
		// 出队列操作
		while(!queue.isEmpty()){
			System.out.print(queue.poll()+" "); // 队列特点先进先出、hello world
		}
		
		// LinkedList源代码初步学习
		/* 定义了一个十分常见的Entry类在HashMap源代码中也看到过
	    private static class Entry<E> { // 静态内部类
	    	E element; // 泛型
	    	Entry<E> next; // 后继结点引用
	    	Entry<E> previous; // 前驱结点引用

			// 构造方法、构建对象时候初始化操作
	    	Entry(E element, Entry<E> next, Entry<E> previous) {
	    	    this.element = element;
	    	    this.next = next;
	    	    this.previous = previous;
	    	}
	     }*/
		
		// LinkedList类中add方法(队列入队操作)
	    /*private transient Entry<E> header = new Entry<E>(null, null, null);
	     * 
	      public LinkedList() {
	      	   //new LinkedList<String>();操作初始化设置为null
	           header.next = header.previous = header; 
	      }
	      
	      // add方法实现
	      public boolean add(E e) {
			   // addBefore方法调用,处理queue.add("hello");方法调用add
			   addBefore(e, header); 
        	   return true;
          }
          // addBefore(e,header)方法 header链表维护关系参数
          private Entry<E> addBefore(E e, Entry<E> entry) {
               // 采用的前驱后继引用方式存储
			   Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
			   newEntry.previous.next = newEntry;
			   newEntry.next.previous = newEntry;
			   size++;
			   modCount++;
			   return newEntry;
			}
		  // poll方法实现类似add从header头部取出元素即可
	    */

	}

}

第四章:串
一、串的定义
   计算机上的非数值处理的对象基本上都是字符串数据。串是由零个或多个字符组成的有限序列。串中字符的数目成为字符串的长度,零个字符的串成为空串。串的模式匹配算法经典的是KMP算法。
二、研究String类
   在java编程语言中提供了String类,下面通过代码简单对该类进行学习。
  学习过程中的代码如下:
/**
 * @author Administrator
 * 
 * @description String类学习测试类
 * @history
 */
public class StringTest {

	/**
	 *@description 
	 *@param args
	 */
	public static void main(String[] args) {
		
// java应用程序有个概念编译期和运行期
// 编译期能够确定的字符串常量、运行期有个常量池的概念

		String str1 = "hello world";
		String str2 = "hello world";
		System.out.println(str1==str2); //true
		
// ==运算符当比较基本数据类型的时候比较的是值大小是否相等,其他比较的是对象在内存的地址值
// equals方法是从根基类Object中继承来的,String类对其进行了覆写,比较的是内容是否相同

		String str3 = new String("hello world");
		System.out.println(str3==str2); //false
		System.out.println(str2.equals(str3)); // true
		
		// string类常用的方法,不要强记,开发看看API就好
		String str = "hello2world";
		System.out.println(str.charAt(0)); //h
		System.out.println(str.substring(0, str.length())); //hello2world
		
		String[] strArray = str.split("2"); // 截取操作
		for(int i=0;i<strArray.length;i++){
			System.out.print(strArray[i]+" ");// hello world
		}
		
// String类和StringBuffer和StringBuilder类的用法差别
// StringBuffer类是使用缓冲期的可变字符串,效率比不可变的String类更快,根据具体场合选择使用
// StringBuffer和StringBuilder类的区别在于方法是否同步的,这个也看具体的场合选择使用

		StringBuffer sb = new StringBuffer("hello");
		sb.append("world"); // StringBuffer的append方法比较常用
		System.out.println(sb.toString()); // toString方法的调用

	}
}

第五章:数组和广义表
一、数组和广义表定义
   数组是读者已经很熟悉的一种数据类型,几乎所有的程序设计语言都把数组类型设为固有的类型。数组的应用中涉及到一个比较重要的数学知识,矩阵的压缩存储问题。广义表是线性表的推广,在java开发中好像用得不多,有时间再进一步学习。
1
2
分享到:
评论

相关推荐

    数据结构与算法分析学习笔记

    数据结构与算法分析学习笔记:我所选择的教材是《数据结构与算法分析——C语言描述》(原书第2版),英文版的名称是《Data Structures and Algorithm Analysis in C》,作者是:(美)Mark Allen Weiss。原书曾被评为...

    数据结构.xmind思维导图(学习笔记)

    一个超级详细的数据结构笔记,以思维导图的形式,可以更好的帮助大家理解知识,建立好的知识体系!还有什么要资料,博主学习后都可以为大家整理出来哦!

    数据结构与算法分析学习笔记chm

    ^_^这本教科书所使用的是C语言,也许很多人会说C语言已经过时了,但是,我认为在数据结构的学习中,应该用尽量简单的语言,以免进入了语言的细枝末节中,反而冲淡了主题。实际上在国外的许多大学中(甚至中学),...

    Oracle 10g 学习笔记

    │ ORACLE学习笔记(二)oracle的逻辑结构 - lvhuiqing的专栏 - CSDN博客.mht.lnk │ ORACLE学习笔记(二)SQLPLUS基础 - lvhuiqing的专栏 - CSDN博客.mht │ ORACLE学习笔记(二)SQLPLUS基础 - lvhuiqing的专栏 - ...

    数据结构 严蔚敏版 学习笔记 第一章____绪论.pdf

    给学习数据结构的大家

    数据结构与算法分析——C语言描述(Weiss著)的学习笔记

    原书曾被评为20世纪顶尖的30部计算机著作之一,作者Mark Allen Weiss在数据结构和算法分析方面卓有建树,他的数据结构和算法分析的著作尤其畅销,并受到广泛好评.已被世界500余所大学用作教材。 在本书中,作者更加...

    数据结构与算法分析学习笔记.chm

    《数据结构与算法分析——C语言描述》(原书第2版),英文版的名称是《Data Structures and Algorithm Analysis in C》,作者是:(美)Mark Allen Weiss。原书曾被评为20世纪顶尖的30部计算机著作之一

    斯坦福机器学习笔记.zip

    机器学习是研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。它是人工智能的核心,是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域,它...

    ES6学习笔记之Set和Map数据结构详解

    本文实例讲述了ES6学习笔记之Set和Map数据结构。分享给大家供大家参考,具体如下: 一.Set ES6提供了新的数据结构Set。类似于数组,只不过其成员值都是唯一的,没有重复的值。 Set本身是一个构造函数,用来生成Set...

    python学习笔记-王纯业

    以下是一个Python学习笔记的大纲,涵盖了从基础到进阶的内容。你可以根据自己的学习进度和理解情况,逐步填充和完善这个大纲。 Python学习笔记大纲 一、Python基础 Python简介 Python的历史 Python的特点和应用...

    ADO学习笔记之一ADO数据访问技术与连接字符串

    VB6动态获得多种数据库的表结构

    严蔚敏数据结构(最全资料之一)

    数据结构最全资料合集,包括电子书、习题集答案、纯C代码、教学讲义和课件,还有数据结构笔记和数据结构1800复习例题与答案。供大家一起共同分享学习。

    Redis学习笔记.pdf.zip

    Redis 已成为Web 开发社区中最火热的内存数据库之一,随着网站数据快速增长,对高性能读写的需求也越来越多,再加上半结构化的数据比重逐渐变大,显得redis更加重要。仅用学习使用,不可用于商业用途,如有版权问题...

    C语言学习笔记

    比如int有几个字节的问题,已经是QQ加群验证是否是程序员的一个标准了(笑),这从侧面说明了学习C语言时确实会关心底层软硬件的实现。C语言简单的基于值类型的数据类型体系(引用靠指针,指针本身也是值类型),...

    Android 工程师成长之路:JAVA算法的实现,数据结构 和 Android源码笔记等 分享.zip

    算法与数据结构涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间...学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

    c#学习笔记.txt

    try-catch 语句采用下列形式之一: try try-block catch (exception-declaration-1) catch-block-1 catch (exception-declaration-2) catch-block-2 ... try try-block catch catch-block (4) fixed 防止变量被...

    javaEE servlet 学习笔记

    javaEE servlet 学习笔记 jsp本质上是servlet,但是为了更加符合mvc的框架,将页面显示和逻辑控制分离,jsp页面只负责页面,也就是mvc中的V(view),而servlet负责mvc中的C(control)。 而为了更加好的理解结构,一下...

    net学习笔记及其他代码应用

    要请求垃圾收集,可以调用下面的方法之一: System.gc() Runtime.getRuntime().gc() 37.String s = new String(\"xyz\");创建了几个String Object? 答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。...

    数据结构和算法----稀疏数组.rar

    学习笔记[韩顺平老师讲的数据结构和算法];数据结构和算法之稀疏数组。个人的一个理解。

Global site tag (gtag.js) - Google Analytics