数据结构之线性表(2)链式存储结构(1)

本文详细介绍了单链表的基本概念及其实现方法,包括遍历、插入和删除等操作的具体步骤,并提供了完整的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线性表的链式存储结构:单链表

特点:逻辑上相邻的元素在物理存储上是不一定相邻的。每个内存单元之间通过指针相连。

 单链表和顺序表的不同点在于存储结构,由于存储位置不连贯,想要找到下个元素,需要指针,也就是地址(java中也叫引用)

 算法的实现还是在代码中,要点还是老样子,记录在注释中。

首先是遍历链表

借助指针,“顺藤摸瓜” (沿着链表访问结点)。

//遍历单链表
	public void visitLinkList(LinkList1 L){
		LinkList1 p = L;
		//P.getNext()方法获取的是LinkList1对象的指针域,这里跟C语言中的L.next是一致的。
		while(p!=null){
			System.out.println(p.getData());
			p =  p.getNext();
		}
	}
	
	@Test
	//测试遍历单链表
	public void testVisitLinkList(){
		//创建对象,并赋值。
		LinkList1 l1 = new LinkList1();
		LinkList1 l2;
		LinkList1 l3;
		l3 = l1;//l3指向头结点
		for(int i = 0 ;i < 6 ;i++){
		    l2 = new LinkList1();//创建新结点l2
		    System.out.println(i);
		    l2.setData(""+i);
		    l3.setNext(l2);//在第一次循环中因为l3指向头结点l1,所以l3的指针域就是头结点l1的指针域,相当于l1.next -> l2
		    l3 = l2;//l3指向新结点。
		}
		l3.setNext(null);
		//遍历l1
		visitLinkList(l1);
		
		//查找指定元素
		LinkList1 q = l1;
		int count = 0;
		while(q!=null){
			if("3".equals(q.getData())){
				System.out.println(count);
			}
			count ++;//查找指定元素的位置或者根据指定位置查找数据都需要借助计数器
			q = q.getNext();
		}
        //		打印结果:
//		0
//		1
//		2
//		3
//		4
//		5
//		null
//		0
//		1
//		2
//		3
//		4
//		5
//		4
	}

插入结点 

思路:
先查找第 i-1 个元素
若找到,在其后插入新结点

//测试插入单链表
	@Test
	public void testInsertLinkList(){
		//创建对象,并赋值。
		LinkList1 l1 = new LinkList1();
		LinkList1 l2;
		LinkList1 l3;
		l3 = l1;//l3指向头结点
		for(int i = 0 ;i < 6 ;i++){
		    l2 = new LinkList1();//创建新结点l2
		    System.out.println(i);
		    l2.setData(""+i);
		    l3.setNext(l2);//在第一次循环中因为l3指向头结点l1,所以l3的指针域就是头结点l1的指针域,相当于l1.next -> l2
		    l3 = l2;//l3指向新结点。
		}
		l3.setNext(null	);
		
		int index = 4; //位置
		int count = 0;
		String data = "test"; //插入元素的数据
		LinkList1 P = l1;
		while(P!=null && count < index-1){
			P = P.getNext();
			count++;
		}
		if(P != null && count == index-1){ //1指针在链表上且2计数器在指定位置
			LinkList1 q = new LinkList1();//创建插入结点
			q.setData(data);//将数据放入插入结点
			q.setNext(P.getNext());//1.插入结点的指针指向指针P所指向的链表结点的指针域。q.next -> P.next
			P.setNext(q);//2.P的指针指向插入结点。p.next -> q 如图。
		}
		visitLinkList(l1);
//		打印结果:
//		null
//		0
//		1
//		2
//		test
//		3
//		4
//		5
	}

 删除结点

思路:
先查找第 i-1 个元素
若找到且其后存在第 i 个元素,则用 x 返回数据,并删除之

//测试删除结点
	@Test
	public void testdeleteLinkNode(){
		//创建对象,并赋值。
		LinkList1 l1 = new LinkList1();
		LinkList1 l2;
		LinkList1 l3;
		l3 = l1;//l3指向头结点
		for(int i = 0 ;i < 6 ;i++){
		    l2 = new LinkList1();//创建新结点l2
		    System.out.println(i);
		    l2.setData(""+i);
		    l3.setNext(l2);//在第一次循环中因为l3指向头结点l1,所以l3的指针域就是头结点l1的指针域,相当于l1.next -> l2
		    l3 = l2;//l3指向新结点。
		}
		l3.setNext(null	);
		
		int index = 4 ; //要删除的位置
		int count = 0; //计数器
		LinkList1 p = l1;
		while(p != null && count < index - 1){
			count ++ ;//计数器自增
			p = p.getNext();//指针后移
		}
		if(p != null && count == index - 1){//1指针在链表上且2计数器在指定位置的前一位置
			System.out.println(p.getNext().getData());//打印要删除结点的数据
			LinkList1 q = p.getNext(); //创建指针指向要删除的结点
			p.setNext(q.getNext());     //删除结点的前一结点的指针域指向删除结点的下一个结点 p.next ->q.next
			p = null;//我们把指针置空,丢弃之前的结点,java的垃圾回收机制会不定时自动回收丢弃的内存。
			q = null;//注意我们用的java所以不需要手动释放内存,在C或者其他语言中需要手动释放丢弃的内存。
		} 
		visitLinkList(l1);
		//打印结果:
//		0
//		1
//		2
//		3
//		4
//		5
//		3
//		null
//		0
//		1
//		2
//		4
//		5
	}

 此外,创建链表的方式也是一个重点,代码中我使用的是顺序建表,即先创建表头,在依次创建结点,上一结点的指针域指向新增结点。还可以逆序建表,首先创建尾结点,创建指针指向尾结点,然后依次创建新节点,指向指针,指正迭代到新创建的节点,在这里就不在代码中演示了。链表的插入删除关键点在于对指针指向的先后问题。

循环链表

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值