记录我学习数据结构之路(八)

线性表的顺序存储的缺点就是插入和删除的时候需要移动大量的数据,这是非常耗时间的。那应该换一种思路,在第一个元素的时候,就知道第二个元素的位置;在第二个的时候就找到了第三个的位置,以此类推。这样,只要记录下下一个的位置了,不管数据存在哪里,都能顺利地找到下一个结点的位置。

代码实现:

/***
 * 单链表节点类
 * @author link
 *
 */
public class Node {
	public int iNum;
	public double dNum;
	public Node next;   //指向下一个结点

	public Node(int i,double d){
		iNum = i;
		dNum = d;
	}

	public void show(){
		System.out.print("{"+iNum+","+dNum+"}");
	}
}
/***
 * 单链表类
 * @author link
 *
 */
public class LinkedList {
	private Node first; //声明结点对象

	public LinkedList(){
		first = null;
	}
	/*
	 * 插入方法:创建一个结点对象,然后让这个结点的下一个结点指向first对象,然后把这个对象赋值给first对象
	 */
	public void insertFirst(int i,double d){
		Node node = new Node(i, d);
		node.next = first;
		first = node;
	}

	public boolean isEmpty(){
		return first == null;
	}
	/*
	 * 删除第一个结点:让下一个节点变成第一个结点就行了
	 */
	public Node deleteFirst(){
		Node temp = first;
		first = first.next;
		return temp;
	}
	/*
	 * 删除某个指定的结点:循环判断当前结点寻找对应的结点后,如果是第一个结点,直接让下一个结点成为第一个结         * 点,如果不是第一个节点,就让当前结点的前一个结点指向当前结点的下一个结点就行了
	 */
	public Node delete(int i){
		Node current = first;//声明当前结点
		Node pervious = first;//声明当前结点的前一个节点
		while(current.iNum != i){
			if(current.next == null)return null;
		else{
			pervious = current;
			current = current.next;
			}
		}
		if(current == first)
			first = first.next;
		else{
			pervious.next = current.next;
		}
		return current;
	}
	/*
	 * 寻找某个结点:循环当前结点,如果找到则推出循环返回结点,如果没找到就指向下一个结点继续寻找
	 */
	public Node find(int i){
		Node current = first;
		while(current.iNum != i){
			if(current.next == null){
				return null;
			}else{
				current= current.next;
			}
		}
		return current;
	}

	public void display(){
		System.out.print("List(first-->last):");
		Node current = first;
		while(current!=null){
			current.show();
			current = current.next;
		}
		System.out.println();
	}
}
/***
 * 测试类
 * @author link
 *
 */
public class LinkListApp {

	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		list.insertFirst(12, 2.3);
		list.insertFirst(42, 3.5);
		list.insertFirst(89, 12.2);
		list.insertFirst(41, 5.5);
		list.insertFirst(21, 2.8);
		list.insertFirst(43, 2.2);
		list.insertFirst(67, 6.9);
		list.display();
		list.delete(89);
		list.display();

		Node temp = list.find(41);
		if(temp != null){
			System.out.println("Found:{"+temp.iNum+","+temp.dNum+"}");
		}else{
			System.out.println("Can not find!");
		}
	}

}

运行结果:

List(first-->last):{67,6.9}{43,2.2}{21,2.8}{41,5.5}{89,12.2}{42,3.5}{12,2.3}

List(first-->last):{67,6.9}{43,2.2}{21,2.8}{41,5.5}{42,3.5}{12,2.3}

Found:{41,5.5}

简单总结一下单链表结构与顺序存储结构的优缺点:在存储分配方式中,顺序存储结构用一段连续的存储单元依次存储线性表的数据元素;单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。在时间性能上,查找数据操作时,顺序存储结构为O(1),单链表为O(n);插入和删除操作时,顺序存储结构需要平均移动表长一半的元素,时间为O(n),单链表在找出某位置的指针后,插入和删除是间仅为O(1)。在空间性能上,顺序存储结构需要预分配存储空间,分大了,浪费,分小了容易发生溢出;单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。

时间: 2024-11-06 11:17:01

记录我学习数据结构之路(八)的相关文章

记录我学习数据结构之路(七)

直接插入排序的基本操作:将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表. 这是书上写的操作,他是把数组的第一个位置空出来,从第二个位置开始开始放入数据,那么空出来的第一个位置就是用来暂时存放取出来的数值的.从数组的第三个位置开始取,取出来之后向前遍历,如果前一个值比它大,那么前一个人往后移动一位,直到找到不比取出来的数值大的,然后就把取出来的值插入那个值后面. 我就不用数组的第一个值作存放取出值了,数组从0位开始存,另外再声明了一个变量来存放取出来的值: public

记录我学习数据结构之路(二)

算法的定义:解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作. 算法的特性:输入.输出.有穷性.确定性和可行性.输入和输出:算法具有零个或多个输入和输出.有穷性:算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成.确定性:算法的每一步骤都具有确定的含义,不会出现二义性.可行性:算法的每一步都必须的可行的,也就是说,每一步都能通过执行有限次数完成. 算法的设计要求:1.正确性:算法至少应该有输入.输出和加工处理无歧义性

记录我学习数据结构之路(四)

首先写一个数组类(这个是按照从小到大排列的数组).插入操作:遍历整个数组,当找到该数据比要插入的数据后就跳出循环,然后从最后一个数据向前遍历,直到遍历到刚刚找到的那个数据项为止,每个数据往后移动一位,最后就往找到的那个位置插入该数值.删除操作:遍历数组,找到要删除的数据项,删除.查找操作:用二分查找法,每次都找到数据中间的一项,如果该项比要查找的数据大,那么把后一般的数据去掉,保留前一半的数据,然后再找前一半数据的中间项,重复这个方法直到找到为止. public class OrderArray

记录我学习数据结构之路(六)

选择排序思路:不像冒泡排序那样每次找到比它小的就交换,而是要选择最小的,只交换一次就够了. 代码实现如下: public void sort(){ int out,in,min; for(out = 0; out < nElement; out++){ min = out; for(in = out+1; in < nElement; in++){ if(a[in] < a[min]){ min = in; } } swap(out,min); } } 选择排序最大的特点就是交换移动数据

记录我学习数据结构之路(九)

双端链表跟传统的单链表不同的地方是,单链表就只有一个first指向头结点的,而双端链表不仅有first指向头结点,而且有一个last指向尾结点. 代码展示: public class Node { public int iNum; public double dNum; public Node next;   //指向下一个结点 public Node(int i,double d){ iNum = i; dNum = d; } public void show(){ System.out.pr

20172328 2018-2019《Java软件结构与数据结构》第八周学习总结

20172328 2018-2019<Java软件结构与数据结构>第八周学习总结 概述 Generalization 本周学习了二叉树的另一种有序扩展?是什么呢?你猜对了!ヾ(?°?°?)??就是堆.本章将讲解堆的链表实现and数组实现,以及往堆中添加元素或从堆中删除元素的算法:还将介绍对的一些用途,包括基本使用和优先队列. 教材学习内容总结 A summary of textbook 堆(heap)就是具有两个附加属性的一颗二叉树: 第一点:它是一颗完全二叉树 ,即叶子节点都在最后一层靠左侧

20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结

20172323 2018-2019-1 <程序设计与数据结构>第八周学习总结 教材学习内容总结 本周学习了第12章优先队列与堆 12.1 堆 堆是具有两个附加属性的一棵二叉树,它是一棵完全树,对于每一结点,它小于或等于其左孩子和右孩子,这样定义下的堆是最小堆,如果对于每一结点,它大于或等于其左孩子和右孩子,那么它就是最大堆. 最小堆将其最小元素存储在该二叉树的根处,且其根的两个孩子同样也是最小堆. 操作 说明 addElement 将给定元素添加到该堆中 removeMin 删除堆的最小元素

2017-2018-20172309 《程序设计与数据结构》第八周学习总结

2017-2018-20172309 <程序设计与数据结构>第八周学习总结 一.教材学习内容总结 相信其它很多同学都是以小顶堆来介绍这一章内容,所以我将以大顶堆来介绍这章内容. 1.1 堆的简单介绍: 堆的定义:(大顶堆) 堆实际上是一棵完全二叉树. 堆满足两个性质: 堆的每一个父节点都大于其子节点: 堆的每个左子树和右子树也是一个堆. 堆的分类: 堆分为两类: 最大堆(大顶堆):堆的每个父节点都大于其孩子节点: 最小堆(小顶堆):堆的每个父节点都小于其孩子节点: 例子: 堆的操作: 堆的定义

20172315 2018-2019-1 《程序设计与数据结构》第八周学习总结

20172315 2018-2019-1 <程序设计与数据结构>第八周学习总结 教材学习内容总结 堆是一棵完全二叉树,其中的每一结点都小于或等于它的两个孩子. 一个堆也可以是最大堆(maxheap),其中的结点大于或等于它的左右孩子. 最小堆将其最小元素存储在该二又树的根处,且其根的两个孩子同样也是最小堆. addElement方法将给定的Comparable元素添加到堆中的恰当位置处,且维持该堆的完全性属性和有序属性. 因为一个堆就是一棵完全树,所以对于插入的新结点而言,只存在一个正确的位置