什么是单链表

  这两天看到很多有关单链表的面试题,对单链表都不知道是啥的我。经过学习和整理来分享一下啥是单链表和单链表的一些基本使用方法。最后看些网上有关单链表的面试题代码实例。

啥是单链表?

  单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。这组存储单元既可以是连续的,也可以是不连续的。

  链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

  链表的结点结构:

      ┌───┬───┐
      │data│next│
      └───┴───┘
  data域--存放结点值的数据域[元素]
  next域--存放结点的直接后继的地址(位置)的指针域(链域)[指针]
 
  用张图来说明一下上面的定义:
 
 
在VS中看到单链表的结构如下图:
 
 

实例代码

单键表结点类-泛型
public class Node<T>
{
public T Data { set; get; } //数据域,当前结点数据
public Node<T> Next { set; get; } //位置域,下一个结点地址 public Node(T item)
{
this.Data = item;
this.Next = null;
} public Node()
{
this.Data = default(T);
this.Next = null;
}
}

public class LinkList<T>
{
public Node<T> Head { set; get; } //单链表头 //构造
public LinkList()
{
Head=null;
} /// <summary>
/// 增加新元素到单链表末尾
/// </summary>
public void Append(T item)
{
Node<T> foot = new Node<T>(item);
Node<T> A = new Node<T>();
if (Head == null)
{
Head = foot;
return;
}
A = Head;
while (A.Next != null)
{
A = A.Next;
}
A.Next = foot;
}
}

1.如果增加的是头结点。直接把数据域(Data)给Head,Next为空。因为只有一个头结点,没有对应的下结点。

2.单链表是”不走回头路“,所以每次增加都要从单链表的头开始找到单链表最后一个结点(最后一个结点就是Next为NULL),然后把最后一个结点的Next设置成需增加的结点,这时要需增加的结点变身为最后一结点,他的Next为NULL。

public class LinkList<T>
{
public Node<T> Head { set; get; } //单链表头 //构造
public LinkList()
{
Head=null;
}
public void Delete(int i)
{
Node<T> A = new Node<T>();
if (i == ) //删除头
{
A = Head;
Head = Head.Next;
return;
}
Node<T> B = new Node<T>();
B = Head;
int j = ;
while (B.Next != null && j < i)
{
A = B;
B = B.Next;
j++;
}
if (j == i)
{
A.Next = B.Next;
}
}
}

1.如果删除的是头结点,那现在的头结点就应该是头结点的下一结点。

2.删除结点如果不是头结点。从单链表头开始查询要删除结点的位置。并记录删除的前一结点值A和所要删除的结点B。因为结点B被删除了,所以结点A的Next就应该为B的Next。把结点A的Next设置为结点B的Next。

单链表类

public class LinkList<T>
{
public Node<T> Head { set; get; } //单链表头 //构造
public LinkList()
{
Clear();
} /// <summary>
/// 求单链表的长度
/// </summary>
/// <returns></returns>
public int GetLength()
{
Node<T> p = Head;
int length = ;
while (p != null)
{
p = p.Next;
length++;
}
return length;
} /// <summary>
/// 判断单键表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
if (Head == null)
return true;
else
return false;
} /// <summary>
/// 清空单链表
/// </summary>
public void Clear()
{
Head = null;
} /// <summary>
/// 获得当前位置单链表中结点的值
/// </summary>
/// <param name="i">结点位置</param>
/// <returns></returns>
public T GetNodeValue(int i)
{
if (IsEmpty() || i< || i>GetLength())
{
Console.WriteLine("单链表为空或结点位置有误!");
return default(T);
} Node<T> A = new Node<T>();
A = Head;
int j = ;
while (A.Next!=null && j<i)
{
A = A.Next;
j++;
} return A.Data;
} /// <summary>
/// 增加新元素到单链表末尾
/// </summary>
public void Append(T item)
{
Node<T> foot = new Node<T>(item);
Node<T> A = new Node<T>();
if (Head == null)
{
Head = foot;
return;
}
A = Head;
while (A.Next != null)
{
A = A.Next;
}
A.Next = foot;
} /// <summary>
/// 增加单链表插入的位置
/// </summary>
/// <param name="item">结点内容</param>
/// <param name="n">结点插入的位置</param>
public void Insert(T item, int n)
{
if (IsEmpty() || n < || n > GetLength())
{
Console.WriteLine("单链表为空或结点位置有误!");
return;
} if (n == ) //增加到头部
{
Node<T> H = new Node<T>(item);
H.Next = Head;
Head = H;
return;
} Node<T> A = new Node<T>();
Node<T> B = new Node<T>();
B = Head;
int j = ;
while (B.Next != null && j < n)
{
A = B;
B = B.Next;
j++;
} if (j==n)
{
Node<T> C = new Node<T>(item);
A.Next = C;
C.Next = B;
}
} /// <summary>
/// 删除单链表结点
/// </summary>
/// <param name="i">删除结点位置</param>
/// <returns></returns>
public void Delete(int i)
{
if (IsEmpty() || i < || i > GetLength())
{
Console.WriteLine("单链表为空或结点位置有误!");
return;
} Node<T> A = new Node<T>();
if (i == ) //删除头
{
A = Head;
Head = Head.Next;
return;
}
Node<T> B = new Node<T>();
B = Head;
int j = ;
while (B.Next != null && j < i)
{
A = B;
B = B.Next;
j++;
}
if (j == i)
{
A.Next = B.Next;
}
} /// <summary>
/// 显示单链表
/// </summary>
public void Dispaly()
{
Node<T> A = new Node<T>();
A = Head;
while (A != null)
{
Console.WriteLine(A.Data);
A = A.Next;
}
} #region 面试题
/// <summary>
/// 单链表反转
/// </summary>
public void Reverse()
{
if (GetLength()== || Head==null)
{
return;
} Node<T> NewNode = null;
Node<T> CurrentNode = Head;
Node<T> TempNode = new Node<T>(); while (CurrentNode!=null)
{
TempNode = CurrentNode.Next;
CurrentNode.Next = NewNode;
NewNode = CurrentNode;
CurrentNode = TempNode;
}
Head = NewNode; Dispaly();
} /// <summary>
/// 获得单链表中间值
/// 思路:使用两个指针,第一个每次走一步,第二个每次走两步:
/// </summary>
public void GetMiddleValue()
{
Node<T> A = Head;
Node<T> B = Head; while (B!=null && B.Next!=null)
{
A = A.Next;
B = B.Next.Next;
}
if (B != null) //奇数
{
Console.WriteLine("奇数:中间值为:{0}", A.Data);
}
else //偶数
{
Console.WriteLine("偶数:中间值为:{0}和{1}", A.Data, A.Next.Data);
}
} #endregion }

调用实例

static void Main(string[] args)
{
LinkList<string> link = new LinkList<string>();
link.Append("A");
link.Append("B");
link.Append("C");
link.Append("D");
link.Append("E");
link.Insert("Head", );
Console.WriteLine("单链表内容:");
link.Dispaly();
link.Delete();
Console.WriteLine("已完成删除单链表中第5行记录数");
link.Dispaly();
Console.WriteLine("查询单链表中第1:{0}.第3:{1}", link.GetNodeValue(), link.GetNodeValue());
Console.WriteLine("面试题-->单链表反转");
link.Reverse();
Console.WriteLine("面试题-->获得单链表中间值");
link.GetMiddleValue();
}

输出结果:

C# 数据结构--单链表的更多相关文章

  1. python实现数据结构单链表

    #python实现数据结构单链表 # -*- coding: utf-8 -*- class Node(object): """节点""" ...

  2. C语言数据结构-单链表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作

    1.数据结构-单链表的实现-C语言 typedef struct LNode { int data; struct LNode* next; } LNode,*LinkList; //这两者等价.Li ...

  3. 数据结构——单链表java简易实现

    巩固数据结构 单链表java实现 单链表除了表尾 每个几点都有一个后继 结点有数据和后继指针组成  通过构建表头和表尾(尾部追加需要)两个特殊几点 实现单链表的一些操作,代码如下 package co ...

  4. 数据结构-------单链表(C++)

    相关信息: /** * @subject 数据结构 实验2 * @author 信管1142班 201411671210 赖俊杰 * @project 单链表 * @time 2015年10月29日1 ...

  5. C# 数据结构 - 单链表 双链表 环形链表

    链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...

  6. 数据结构—单链表(类C语言描写叙述)

    单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...

  7. python算法与数据结构-单链表(38)

    一.链表 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括 ...

  8. 数据结构——单链表(singly linked list)

    /* singlyLinkedList.c */ /* 单链表 */ /* 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素. */ #include <stdio ...

  9. 数据结构-单链表-类定义2-C++

    上一次的C++链表实现两个单链表的连接不太理想,此次听了一些视频课,自己补了个尾插法,很好的实现了两个链表的连接,当然了,我也是刚接触,可能是C++的一些语法还不太清楚,不过硬是花了一些时间尽量在数据 ...

随机推荐

  1. MEF 编程指南(四):声明导入

    组合部件通过 [System.ComponentModel.Composition.ImportAttribute] 特性声明导入.类似于导出,也有几种不同的方法声明导入,即通过:字段(Fields) ...

  2. Invoke-Express 执行多个批处理命令的函数

    function Mult_ping ($ips) { # $cmdline = "PIng" foreach ($ip in $ips) { $cmdline = "p ...

  3. 【转】c++笔试题

    原文:http://blog.csdn.net/dongfengsun/article/details/1541926 ①链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题. ...

  4. php7.0 redis扩展下载地址

    http://windows.php.net/downloads/pecl/snaps/redis/20160319/

  5. Educational Codeforces Round 1 C. Nearest vectors 极角排序

    Partial Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/598/problem/ ...

  6. delphi 查找对话框

    调用查找对话框 关键点 HTMLID_FIND = 1; //查找对话框 HTMLID_VIEWSOURCE= 2; //用记事本查看源代码 HTMLID_OPTIONS =3; //Internet ...

  7. HDU 1498 50 years, 50 colors (行列匹配+最小顶点覆盖)

    题目:点击打开链接 题意:每个格子有不同颜色的气球用不同数字表示,每次可选某一行              或某一列来戳气球.每个人有K次机会.求最后哪些气球不能在             k次机会内 ...

  8. iOS开发——Metal教程

    Metal Swift教程   学习使用苹果GPU加速3D绘图的新API:Metal!   在iOS 8里,苹果发布了一个新的接口叫做Metal,它是一个支持GPU加速3D绘图的API.   Meta ...

  9. Invalidate、RedrawWindow与UpdateWindow

    Invalidate.RedrawWindow与UpdateWindow的区别 Invalidate()是强制系统进行重画,但是不一定就马上进行重画.因为Invalidate()只是通知系统,此 时的 ...

  10. 《Entity Framework 6 Recipes》中文翻译——第十章EntityFramework存储过程处理(八)

    将插入.更新和删除操作映射到存储过程 问题 您想在存储过程中映射插入.更新和删除操作. 解决方案 下图所示的运动员Athlete实体模型.底层数据库有一张运动员Athlete表.您想使用存储过程进行实 ...