实现在单向链表中,返回某个节点的前驱.
原理说明
单向链表的特点是链表只有一个方向,即只有从前驱结点指向后继结点的指针,而没有后继节点指向前驱结点的指针,结构图大致如下:
从图可以看出,如果我们要访问第三个结点,我们只能从头指针依次便利每个后继结点,直至访问到第三个结点,因此在单向链表中,我们查找某个元素的时间复杂度
基于链表的单向特点,因此我们必须从头开始遍历才能找到某个节点的前驱.以上图为例进行讲解,假如我们要寻找第三个结点的前驱,我们如何实现呢?
-
首先我们需要申明两个临时变量pre 和 cur,分别指向Head 头结点和Head->next(为null或为第一个结点),这样pre和cur就构成一个相关的对,pre表示cur的前驱,当cur到达第三个结点时,此时pre就是我们要找的前驱.
- 再循环中,我们依次把pre和cur向前同时推进,直至cur到达事先定义的结点.
-
在上图中,cur=1,不是我们要找的结点3,因此pre和cur向前移动,即pre=cur, cur=next;
-
此时,cur=2,不符合我们的条件,我们继续执行上面的操作;
现在cur=3,满足我们的条件,此时pre就是他的前驱,返回该节点即可.
下面是实现代码,仅供参考
c语言
#include
#include
#include
// 数据类型
typedef int ElementType;
// 链表数据结构
typedef struct ListNode
{
ElementType data;
struct ListNode* next;
}Node, *Linklist;
// 创建链表
Linklist createList()
{
int len;
printf("请输入链表长度:");
scanf("%d", &len);
Linklist head = (Linklist)malloc(sizeof(Node));
Linklist tail = head;
tail->next = NULL;
for (int i=0; idata = val;
node->next = tail->next;
tail->next = node;
tail = node;
}
return head;
}
// 查找给定节点的前驱
Node* preNodeOf(Linklist list, Node* node)
{
Node* cur = list->next;
Node* pre = list;
while (cur != NULL && cur->data != node->data)
{
pre = cur;
cur = cur->next;
}
if (pre != list)
return pre;
else
return NULL;
}
// 根据索引查找指定节点,index 从1开始
Node* getNode(Linklist list, int index)
{
Node* node = list;
for (int i=0; inext;
if (node == NULL)
return NULL;
}
return node;
}
// 显示链表内容
void showLinklist(Linklist list)
{
Node* node = list->next;
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
int length(Linklist list)
{
int len = 0;
Node* node = list->next;
while (node != NULL)
{
++len;
node = node->next;
}
return len;
}
int main()
{
Linklist list = createList();
printf("链表内容:");
showLinklist(list);
int len = length(list);
int index;
printf("\n输入需要查找前驱的节点的索引(0< n <=%d):", len);
scanf("%d", &index);
Node* node = getNode(list, index);
printf("第%d个节点的内容:%d\n", index, node->data);
node = preNodeOf(list, node);
if (node != NULL)
printf("%d\n", node->data);
else
printf("该节点为第一个节点,无前驱节点!");
return 0;
}
C++代码:这里使用了模板类
#include
using namespace std;
// 节点类, 使用了模板类,方便数据类型
template
class Node
{
public:
T data;
Node* next;
public:
Node(){}
Node(T v, Node* node)
{
this->data = v;
this->next = node;
}
};
template
class LinkList
{
private:
Node* head;
Node* tail;
int count;
public:
LinkList();
~LinkList();
int size();
Node* getNode(int);
void print();
void append(T data);
Node* preNodeOf(Node*);
};
// 初始化链表
template
LinkList::LinkList(): count(0)
{
head = new Node;
head->next = NULL;
tail = head;
int length;
cout << "请输入链表初始长度:";
cin >> length;
for (int i = 0; i < length; ++i)
{
T data;
cout << "第" << (i+1) << "个节点的内容:";
cin >> data;
append(data);
}
}
template
LinkList::~LinkList()
{
Node* node = head->next;
Node* tmp;
while (node != NULL)
{
tmp = node;
node = node->next;
delete tmp;
}
delete head;
head = NULL;
tail = NULL;
}
// 返回链表的长度
template
int LinkList::size()
{
return count;
}
template
Node* LinkList::getNode(int index)
{
if (index > count || index <= 0)
{
cout<< "Index Error!"<* node = head;
for(int i=0; inext; ++i)
{
node = node->next;
}
return node;
}
template
void LinkList::print()
{
Node* node = head->next;
while (node)
{
cout << node->data << " ";
node = node->next;
}
cout<
void LinkList::append(T data)
{
Node* node = new Node();
node->data = data;
node->next = NULL;
tail->next = node;
tail = node;
++count;
}
template
Node* LinkList::preNodeOf(Node* node)
{
Node* pre = head;
Node* cur = head->next;
while (cur->data != node->data)
{
pre = cur;
cur = cur->next;
}
if (pre == head)
{
return NULL;
}
else
{
return pre;
}
}
int main()
{
LinkList list = LinkList();
cout << "链表内容:";
list.print();
int size = list.size();
int index;
cout << "输入需要查找前驱的节点的索引(1 <= n <=" << size << "):";
cin >> index;
Node* node = list.getNode(index);
cout << "第" << index << "个节点的内容:" << node->data << endl;
Node* pre = list.preNodeOf(node);
if (pre)
cout << "第" << index << "个节点的前驱:" << pre->data << endl;
else
cout << "该节点为第一个节点,无前驱" << endl;
return 0;
}
下面的代码仅供学习使用,课程要求为C/C++变成语言.
Python3
class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next
class LinkList:
def __init__(self):
self._head = Node(0)
self._tail = self._head
self._count = 0
def append(self, data):
node = Node(data, None)
self._tail.next = node
self._tail = node
self._count += 1
def size(self):
return self._count
def show(self):
node = self._head.next
while (node):
print(node.data, end=" ")
node = node.next
def add_n_elems(self, n):
for i in range(n):
data = int(input("请输入第%d个节点的内容:" % (i+1)))
self.append(data)
def pre_node_of(self, node):
pre = self._head
cur = pre.next
while(cur.data != node.data):
pre = cur
cur = cur.next
if (pre == self._head):
return None
else:
return pre
def get_node(self, index):
if not (1 <= index <= self.size() ):
raise Exception("Index Error!")
node = self._head
for _ in range(index):
node = node.next
return node
if __name__ == "__main__":
linklist = LinkList()
length = int(input("请输入链表长度:"))
linklist.add_n_elems(length)
print("链表内容:", end="")
linklist.show()
index = int(input("\n输入需要查找前驱的节点的索引(0< n <=%d):" % linklist.size()))
node = linklist.get_node(index)
pre_node = linklist.pre_node_of(node)
print("第%d个节点的内容:%d" % (index, node.data))
if pre_node is not None:
print("第%d个节点的前驱的内容内容:%d" % (index, pre_node.data))
else:
print("该节点无前驱节点")
Java
import java.util.Scanner;
class Node {
public T data;
public Node next;
public Node(){}
public Node(T data) {
this.data = data;
this.next = null;
}
}
class Linklist {
private Node head;
private Node tail;
private int count;
public Linklist() {
head = new Node();
tail = head;
count = 0;
}
public void append(T data)
{
Node node = new Node(data);
tail.next = node;
tail = node;
count++;
}
public int size() {
return count;
}
public Node getNode(int index) throws Exception{
if (index < 1 || index > count)
throw new Exception("Index Error!");
Node node = head;
for (int i=0; i preNodeOf(Node node) {
Node pre = head;
Node cur = pre.next;
while (cur.data != node.data) {
pre = cur;
cur = cur.next;
}
if (pre == head)
return null;
else
return pre;
}
public void show() {
Node node = head.next;
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
}
public class Demo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Linklist list = new Linklist();
int length;
System.out.print("请输入链表长度:");
length = scan.nextInt();
for (int i=0; i node;
try {
node = list.getNode(index);
} catch (Exception e) {
// e.printStack();
node = null;
}
Node pre_node = list.preNodeOf(node);
System.out.println("第" + index + "个节点的内容:" + node.data);
if (pre_node != null)
System.out.println("第" + index + "个节点的前驱的内容内容:" + pre_node.data);
else
System.out.println("该节点无前驱节点");
}
}