Java实现线性表的就地逆序方法

所谓的线性表即每个数据元素具有确定的位置,数据得组织方式又有顺序存储和链式存储,接下来我们线性表中的顺序表及链表的就地逆序问题进行讨论:

1.对于线性表中的顺序存储

顺序表的结构
在这里插入图片描述
比较容易理解的写法:

public void inverseSqList() {
	Object temp;//定义交换变量
	for (int i = 0; i < curLen/2; i++) {
	//将a[0]与a[n]进行交换 然后是a[1]与a[n-1]交换,以此类推,进行顺序表的长度的一半次运算
		temp = listElem[i];
		listElem[i] = listElem[curLen-i-1];
		listElem[curLen-i-1] = temp;
	}
}

另一种写法:

public void inverseSqList() {
	Object temp;
	for (int i = 0,j = curLen -1; i < j; i++,j--) {
		temp = listElem[i];
		listElem[i] = listElem[j];
		listElem[j] = temp;
	}
}

2.对于线性表中的链式存储

1.不带头结点单链表的就地逆序:

节点类的定义方式:

class Node<T> {
	T data;
	Node<T> next;

	Node(T data, Node<T> next){
		this.data = data;
		this.next = next;
	}

}
	public void inverseLinkList() {
		//单链表为空或只有一个元素,不用进行逆置操作
		if(head == null || head.next == null )
			return ;
		//定义三个指针;
		Node<T> p = head;//令p为头指针,先指向第0个元素
		Node<T> q = head.next;//令q先指向第1个元素
		Node<T> t = null;//令t为空作为交换元素
		
		while(q != null) {
			t = q.next;
			q.next = p;
			p = q;
			q = t;
		}
		head.next = null;//令交换后的最后一个元素指向空;
		head = p;//交换后的第0个元素的头设置为P
    }

下面的草图作为辅助理解的方式:
在这里插入图片描述
2.带头结点单链表的就地逆序:

节点类定义:

class Node<T>{
	T data;
	Node<T> next;
	Node(T data, Node<T> next){
		this.data = data;
		this.next = next;
	}
}

构造方法:

LinkListWithHeadNode(){
	head = new Node<>(null,null);
	size = 0;
}
public void inverseLinkList() {
	//单链表为空或只有头结点或只有一个元素,不用进行逆置操作
	if(head == null || head.next == null || head.next.next == null )
		return;
	//定义三个指针:
	Node<T> p = head.next;//P先指向第0个元素
	Node<T> q = head.next.next;//q先指向第二个元素
	Node<T> t = null;//作为交换指针
	
	while(q != null) {
		t = q.next;
		q.next = p;
		p = q;
		q = t;
	}
       head.next.next = null;//令交换后的最后一个元素指向空;
       head.next = p;//交换后的第0个元素的头设置为P
}

在这里插入图片描述
3.带头结点循环链表的就地逆置:

节点类定义:

class Node<T> {
	T data;
	Node<T> next;

	Node(T data, Node<T> next){
		this.data = data;
		this.next = next;
	}

}

构造方法:

CircularLinkListWithHeadNode() {
	head = new Node<>(null, null);
	head.next = head;//循环
	size = 0;
}
public void inverseCircularLinkListWithHeadNode() {
	//单链表为空或只有头结点或只有一个元素,不用进行逆置操作
	if(head == null || head.next == head || head.next.next == head )
		return;
	Node<T> p = head.next;
	Node<T> q = head.next.next;
	Node<T> t = null;
	
	while(q != head) {
		t = q.next;
		q.next = p; 
		p = q;
		q = t;
	}
       head.next.next = head;//令交换后的最后一个元素指向头节点
       head.next = p;
   }

带头结点循环链表的就地逆置与带头结点的单链表的就地逆置没有太多的差别,只是最后 ‘交换后的最后一个元素指向头节点’循环起来就可以了;

4.带头结点双向链表(设置head和tail,分别指向第1个和最后1个结点)的就地逆置:

节点类,采用的是内部类:

static class Node<T>{
	private T data;
	Node<T> leftEnd;
	Node<T> rightEnd;
	private Node(T data, Node<T> leftEnd,Node<T> rightEnd){
		this.data = data;
		this.leftEnd = leftEnd;
		this.rightEnd = rightEnd;
	}
}
public void inverseDoubleLinkList() {
	//单链表为空或只有头结点或只有一个元素,不用进行逆置操作
	if(head == null || head.rightEnd == null)
		return;
	Node<T> p = head;
	Node<T> q = head.rightEnd;
	Node<T> t = null;
	
	while(q != null) {
		t = q.rightEnd;
		q.rightEnd = p;
		p = q;
		q = t;
	}
	head.rightEnd = null;
	tail = head;
	head = p;
	return;
   }

不带头结点双向链表的就地逆置与不带头结点的单链表的就地逆置没有太多的差别,只是最后 ‘交换后的最后一个元素右节点指空’然后,头尾在交换就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值