算法笔记(二):链表与实现JAVA链表的增删改查

导读:

         链表是什么?为什么要使用链表?链表和数组的区别在哪里?等等这些都需要我们去解读的。我们学习链表的数据结构,就可以彻底的懂得计算机磁盘的底层存储结构的优缺点。让我们来开始链表的学习吧!


一、什么是链表?

         链表是一种物理存储单元上非连续、非顺序的存储结构。——摘自《百度百科》

         其实,这么说是算是准确的,链表不讲究非得像数组一样顺序存储,所谓的顺序链表的存在也仅仅是数据的升序和降序的使用罢了。如果说数组有很多的有点,比如时间复杂度等等都比链表快,为什么还会存在链表呢?这就是数组存储和链式存储的问题了。举个例子,如果我们计算机磁盘是使用数组存储,那么我们把磁盘总容量分成一定数量分块,每块存储容量为一定的磁盘小分块,现在我刚从电脑里删除了一个200MB容量的文件,现在想装300MB的文件(假设)进入电脑中。根据数据顺序存储的性质,我删除了这个200MB文件后磁盘中将出现200MB空缺的磁盘容量,若装入300MB的文件需要另外在磁盘剩余充足的容量区域开辟一个300MB容量的内存空间来存储这个文件,如下图所示。

          

可以肯定的说,磁盘一定不是数组存储的,否则我的磁盘总是不被最大化利用,那得花多少钱去买多大的磁盘呀?

             所以,磁盘是链式方式存储结构的 。

             那么磁盘是链式存储的,那么它是怎么存的呢?如下图所示

                

           很简单,先把200MB删除后磁盘空缺的空间占用,后100MB的就可以在磁盘的空余空间继续开辟空间。

 总结:

               链表的链式结构。这样的好处可以将剩余的空间很好的利用起来,将空间利用率达到最大化。坏处就是增删改查的时间复杂度相对于数组很慢。所以用某种数据结构前应该对实际情况进行思考和均衡才作出决定。

          


二、链表的结构和特点

 1.链表的结构

        单向链表特点:

                      (1)存在唯一的一个被称作“第一个”的数据元素;

                      (2)存在唯一的一个被称为“最后一个”的数据元素;

                      (3)除第一个之外,集合中的每个数据元素均只有一个前驱;

                      (4)除了最后一个之外,集合中每个数据元素均只有一个后继。

       这个什么意思呢?其实很简单,单向链表的每个空间对应一个数据,这就是一对一的关系,也就是所谓的线性结构。在JAVA中,建立链表是没有像C++等语言拥有指针的表达语法,但是存在类似于指针的概念,因为JVM的存在,所以JAVA建立指针空间指向的问题直接可以用等于号来处理  。如

         node.next = por // node的下一个指针指向por空间

                 这个就是node的下个空间是por,让node—》por方式链接起来了。

2.链表的特点

               链表的特点和上列的介绍差不多,拥有数组无法比拟的特点就是可以自由的在任意位置进行插入,而且不用数据扭动,而不像数组的插入数据后大规模的数据往前或者往后移动,所以比起数组的插入,链表的插入是很方便的。同时数组长度是固定的,链表的长度是可变的。(ArrayList除外,但是底层还是使用链表来实现)


三、链表的java实现

          这里附单向链表的代码



public class Nodetest {

	private Node head; // 定义一个头节点
	private static Node current; // 记录当前节点
	private static int data;

	public static void main(String[] args) {

		Nodetest myList = new Nodetest();
		for (int i = 0; i < 6; i++) {
			myList.addData(i); // 循环添加5个元素
		}
		myList.printList(myList.head); // 打印链表

//		// myList.addData(3);
//		System.out.println();
//		myList.printList(myList.head);// 缺少头插和中间插入函数
		myList.increse(myList.head, 1, 8);
		System.out.println();
		myList.printList(myList.head);
//		myList.searchdata(myList.head, 0);
//		System.out.println();

//		myList.change(myList.head, 2, 7);
//		myList.printList(myList.head);
//		System.out.println();
//		myList.delData(myList.head,1);
//		myList.printList(myList.head);
	}

	// 往链表中添加数据
	private void addData(int data) {
		if (head == null) {
			head = new Node(data); // 如果头节点为空,就新建一个头结点
			current = head; // 记录当前节点为头结点
		} else {
			current.next = new Node(data); // 新建一个节点,当前节点的指针域指向它
			current = current.next; // 当前节点位置后移
		}
	}

	// 打印链表
	private void printList(Node head) {
		if (head != null) { // 确定链表不为空
			current = head;
			if (current.next != null) { // 最后一个节点的为空
				System.out.print(current.data + "-->");
				current = current.next; // 当前节点往后移动一个位置
				printList(current);
			} else {
				System.out.print(current.data);
			}
		}
	}

	// 寻找数据
	private void searchdata(Node node, int data) {
		if (node == null) {
			System.out.println("找不到该数据");
		} else {
			if (node.data == data) {
				System.out.println("找到了该数据" + node.data);
			} else {
				if (node.next != null) {
					if (node.data == data) {
						System.out.println("找到了该数据" + node.data);
						
					} else {
						node = node.next;
						searchdata(node, data);
					}
				} else {
					System.out.print("没有找到了数据");
				}
			}
		}
	}
     // 改数据
	private void change(Node node, int data, int newdata) {
		if (head == null) {
			System.out.println("链表没有数据,修改失败");
		} else {
			if (node.data == data) {
				node.data = newdata;
			} else {
				if (node.next != null) {
					if (node.data == data) {
						System.out.println("找到了修改数据" + node.data);
						node.data = newdata;
					} else {
						node = node.next;
						change(node, data, newdata);
					}
				} else {
					System.out.print("没有找到了修改的数据");
				}
			}
		}
	}
	//全能添加
	private void increse(Node node,int Currtdata,int insertData) {
		/*
		 * 往后添加移动
		 */
		if (head == null) {
			head = new Node(insertData); // 如果头节点为空,就新建一个头结点
			current = head; // 记录当前节点为头结点
		} else {
			if (node.data == Currtdata) {
				System.out.println("找到了该数据" + node.data);
			} else {
				if (node.next != null) {
					if (node.data == Currtdata) {
						System.out.println("增加该数据" + node.data);
						Node newnode = null;
						newnode.data = insertData;
						newnode = node.next;						
						node = newnode;
					} else {
						node = node.next;
						increse(node, Currtdata,insertData);
					}
				} else {
					System.out.print("没有找到了数据");
				}
			}
		}
	}
	
	// 删除
	private void delData(Node node, int del) {
		if (node == null) {
			System.out.println("链表没有数据,删除失败");
		} 
		else if(node.data == del){
			System.out.println("找到了删除数据" + node.data);
			head = node.next;//头部删除
			node = null;
		}
		else {
			if (node.next.next != null) {
				if (node.next.data == del) {
					System.out.println("找到了删除数据" + node.next.data);
					Node temp;//建立一个指针指向。
					temp = node.next;
					node.next = node.next.next;//下个结点等于这个。
					temp.next = null;
				} else {
					node = node.next;
					delData(node, del);
				}
			} else {
				if(node.next.data == del){
					System.out.println("找到了删除数据" + node.next.data);
					node.next = null;//尾部删除
				}
				else{System.out.print("没有找到了删除的数据");}
			}
		}
	}
}

    谢谢大家观看~~~比心~= ~=*

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值