数据结构第二次作业

实现在单向链表中,返回某个节点的前驱.

原理说明

单向链表的特点是链表只有一个方向,即只有从前驱结点指向后继结点的指针,而没有后继节点指向前驱结点的指针,结构图大致如下:

数据结构第二次作业_第1张图片
linklist1.png

从图可以看出,如果我们要访问第三个结点,我们只能从头指针依次便利每个后继结点,直至访问到第三个结点,因此在单向链表中,我们查找某个元素的时间复杂度
.

基于链表的单向特点,因此我们必须从头开始遍历才能找到某个节点的前驱.以上图为例进行讲解,假如我们要寻找第三个结点的前驱,我们如何实现呢?

  1. 首先我们需要申明两个临时变量pre 和 cur,分别指向Head 头结点和Head->next(为null或为第一个结点),这样pre和cur就构成一个相关的对,pre表示cur的前驱,当cur到达第三个结点时,此时pre就是我们要找的前驱.


    数据结构第二次作业_第2张图片
    linklist2.png
  2. 再循环中,我们依次把pre和cur向前同时推进,直至cur到达事先定义的结点.
  • 在上图中,cur=1,不是我们要找的结点3,因此pre和cur向前移动,即pre=cur, cur=next;


    数据结构第二次作业_第3张图片
    linklist3.png
  • 此时,cur=2,不符合我们的条件,我们继续执行上面的操作;


    数据结构第二次作业_第4张图片
    linklist4.png

    现在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("该节点无前驱节点");


    }
}

你可能感兴趣的:(数据结构第二次作业)