• C#数据结构三:单链表Singly Linked List


    单链表

    单链表(Singly Linked List),也称单向链表,链表中的一种,其特点链接方向是意向的,对链表的访问要通过顺序读取。在顺序链表中元素之间紧密相连,为了表示两个数据元素逻辑上的相邻关系,除了存储数据元素本身的信息外,还要存储与其相邻的下一数据元素的存储地址信息,也就是指针信息,也叫引用域。数据元素信息和指针信息组成该数据元素的存储映像,这就是节点(Node)。

    数据域也可使用data表示,指针域使用next表示。

    这样线性表就通过每个结点的指针域形成了一根“链条”,也就是我们所说的“链表”。如果结点的引用域只存储该节点直接后继节点的指针域,则该链表称为单链表(Singly Linked List)。单链表结构如下图(图片来自wikipedia):

    单链表:

    1、末端节点的指针域为空,表示链表的结束;

    2、元素间的物理关系是松散的;

    3、每一节点存储实际数据,及下一节点的指针,来实现逻辑上的关联。

    若末端节点的指针指向头节点,则此链表形成环状,称为单向循环链表(Circularly Linked List);此时的终端节点也就失去了其意义。

    单链表实现

    1、节点定义:

    节点类图如下

    代码
    /// <summary>
    /// 节点定义
    /// </summary>
    public class Node<T>
    {
    private T data;//数据域
    private Node<T> next;//引用域
    /// <summary>
    /// 构造器,数据值为输入数据值
    /// </summary>
    /// <param name="val"></param>
    public Node(T val)
    {
    data
    = val;
    next
    = null;
    }
    /// <summary>
    /// 构造器,数据值为系统默认值
    /// </summary>
    public Node()
    {
    data
    = default(T);
    next
    = null;
    }
    /// <summary>
    /// 数据域属性
    /// </summary>
    public T Data
    {
    get {return data;}
    set { data = value; }
    }
    /// <summary>
    /// 引用域属性
    /// </summary>
    public Node<T> Next
    {
    get { return next; }
    set { next = value; }
    }
    }

    2、单链表实现

    单链表类图如下:

    代码如下:

    代码
    /// <summary>
    /// 单链表实现
    /// </summary>
    public class SinglyLinkedList<T>:IListDS<T>
    {
    private Node<T> head;
    /// <summary>
    /// 单链表的头节点
    /// </summary>
    public Node<T> Head
    {
    get { return head; }
    set { head = value; }
    }
    /// <summary>
    /// 构造器,构造具有空指针的头节点
    /// </summary>
    public SinglyLinkedList()
    {
    head
    = null;
    }
    /// <summary>
    /// 求单链表长度
    /// </summary>
    /// <returns></returns>
    public int GetLength()
    {
    Node
    <T> currNode = head;
    int length = 0;
    while (currNode != null)
    {
    ++length;
    currNode
    = currNode.Next;
    }
    return length;
    }
    /// <summary>
    /// 清空单链表
    /// </summary>
    public void Clear()
    {
    head
    = null;
    }
    /// <summary>
    /// 判断单链表是否为空
    /// </summary>
    /// <returns></returns>
    public bool IsEmpty()
    {
    return (head == null) ? true : false;
    }
    /// <summary>
    /// 在单链表末尾添加新元素
    /// </summary>
    /// <param name="item"></param>
    public void Append(T item)
    {
    Node
    <T> newNode = new Node<T>(item);
    Node
    <T> currNode = null;
    if (head == null)
    {
    head
    = newNode;
    return;
    }
    currNode
    = head;
    while (currNode.Next != null)
    {
    currNode
    = currNode.Next;
    }
    currNode.Next
    = newNode;
    }
    /// <summary>
    /// 在指定位置插入元素
    /// </summary>
    /// <param name="item"></param>
    /// <param name="pos"></param>
    /// <returns></returns>
    public bool Insert(T item, int pos)
    {
    if (IsEmpty() || pos < 0)
    {
    Console.WriteLine(
    "The list is empty");
    return false;
    }
    Node
    <T> newNode = new Node<T>(item);
    if (pos == 0)
    {
    newNode.Next
    = head;
    head
    = newNode;
    return true;
    }
    Node
    <T> currNode = head.Next;
    Node
    <T> preNode = head;
    int index = 1;
    while (currNode.Next != null && index < pos)
    {
    preNode
    = currNode;
    currNode
    = currNode.Next;
    ++index;
    }

    if (index == pos)
    {
    newNode.Next
    = currNode;
    preNode.Next
    = newNode;
    return true;
    }
    else
    {
    Console.WriteLine(
    "The position is error");
    return false;
    }
    }
    /// <summary>
    /// 删除指定索引位置的元素
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public T Delete(int pos)
    {
    if (IsEmpty() || pos < 0)
    {
    Console.WriteLine(
    "The Link is empty");
    return default(T);
    }

    T data
    = default(T);
    if (pos == 0)
    {
    data
    = head.Data;
    head
    = head.Next;
    return data;
    }
    Node
    <T> preNode = this.head;
    Node
    <T> currNode = this.head.Next;
    int index = 1;
    while (currNode.Next != null && index < pos)
    {
    ++index;
    preNode
    = currNode;
    currNode
    = currNode.Next;
    }

    if (index == pos)
    {
    preNode.Next
    = currNode.Next;
    return currNode.Data;
    }
    else
    {
    Console.WriteLine(
    "The position is out of range");
    return default(T);
    }
    }
    /// <summary>
    /// 根据索引查找
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public T GetElem(int pos)
    {
    if (IsEmpty())
    {
    Console.WriteLine(
    "The list is empty");
    return default(T);
    }
    Node
    <T> currNode = head;
    int index = 0;
    while (currNode.Next != null && index < pos)
    {
    ++index;
    currNode
    = currNode.Next;
    }
    if (index == pos)
    return currNode.Data;
    else
    {
    Console.WriteLine(
    "The position is out of range");
    return default(T);
    }
    }
    /// <summary>
    /// 根据值查找
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public int Locate(T value)
    {
    if (IsEmpty())
    {
    Console.WriteLine(
    "The list is empty");
    return -1;
    }
    Node
    <T> currNode = new Node<T>();
    currNode
    = head;
    int pos = -1;
    while (currNode != null && currNode.Data.Equals(value))
    {
    currNode
    = currNode.Next;
    ++pos;
    }
    if (currNode == null)
    return -1;

    return pos;
    }
    }

    调用演示:

    代码
    /// <summary>
    /// 功能:单链表演示
    /// 开发:walkingp
    /// 时间:2010-4-29
    /// 主页:http://www.51obj.cn/
    /// </summary>
    class Program
    {
    static void Main(string[] args)
    {
    SinglyLinkedList
    <string> demoList = new SinglyLinkedList<string>();

    /*添加*/
    demoList.Append(
    "Wang Hongjian");
    demoList.Append(
    "ZhangSan");
    demoList.Append(
    "LiSi");
    for (int i = 0; i < demoList.GetLength(); i++)
    {
    Console.WriteLine(
    "The {0} item is:\t{1}",i, demoList.GetElem(i));
    }
    /*插入*/
    Console.WriteLine(
    "Insert the item:");
    demoList.Insert(
    "Zhangyu", 1);
    for (int i = 0; i < demoList.GetLength(); i++)
    {
    Console.WriteLine(
    "The {0} item is:\t{1}", i, demoList.GetElem(i));
    }
    /*删除*/
    Console.WriteLine(
    "Delelte the item:");
    demoList.Delete(
    3);
    for (int i = 0; i < demoList.GetLength(); i++)
    {
    Console.WriteLine(
    "The {0} item is:\t{1}", i, demoList.GetElem(i));
    }
    /*根据索引查找*/
    Console.WriteLine(
    "The 2st item is:\t{0}", demoList.GetElem(1));
    /*根据值查找*/
    Console.WriteLine(
    "The position of the item 'Wang Hongjian' is:\t{0}",demoList.Locate("Wang Hongjian"));
    /*清空*/
    demoList.Clear();
    Console.WriteLine(
    "Now the list is empty");
    }

    演示效果:

    源码下载

    ========================================================

    C#数据结构系列文章:

    1、基础知识

    2、顺序表Sequence List

    3、单链表Singly Linked List

    4、双向链表Double Linked List

    5、循环链表Circular Linked List

    6、栈Stack

    7、队列Queue

    8、串

    9、数组Array

    10、树Tree

    ...

    我的主页:http://www.51obj.cn/

  • 相关阅读:
    学习windows编程 day4 之视口和窗口
    学习windows编程 day4 之 映射模式
    学习windows编程 day4 之 盯裆猫
    Android自动化测试(UiAutomator)简要介绍
    UltraEdit正则表达式介绍及实例
    addr2line -f -e *.so 0x9d69
    Android执行shell命令
    Drawable、Bitmap、byte[]之间的转换
    Ubuntu 12.04 64bit 配置完android 5.0编译环境后出现“could not write bytes: Broken pipe.”而无法进入输入帐号密码的登陆界面
    CameraTest
  • 原文地址:https://www.cnblogs.com/walkingp/p/1724494.html
Copyright © 2020-2023  润新知