数据结构之单链表,c#实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DataStructure
{
class MySingleLinkedList<T> : MyIList<T>
{ private Node<T> head; public Node<T> Head
{
get { return head; }
set { head = value; }
} public MySingleLinkedList()
{
head = null;
} public MySingleLinkedList(Node<T> p)
{
head = p;
} /// <summary>
/// 求单链表的长度
/// 求单链表的长度与顺序表不同。顺序表可以通过指示表中最后一个数据元素的last直接求得,因为顺序表所占用的空间是连续的空间,而单链表需要从头引用开始,一个结点一个结点遍历,直到表的末尾。
/// </summary>
/// <returns></returns>
public int GetLength()
{
if (IsEmpty())
{
return 0;
}
else
{
Node<T> p = head;
int i = 1;
while (p.Next != null)
{
p = p.Next;
i++;
}
return i;
#region 人家是这么写的
//int len = 0;
//while (p != null)
//{
// ++len;
// p = p.Next;
//}
//return len;
#endregion
}
} /// <summary>
/// 清空操作
/// 清空操作是指清除单链表中的所有结点使单链表为空,此时,头引用head为null。
/// </summary>
public void Clear()
{
head = null;
} /// <summary>
/// 判断单链表是否为空
/// 如果单链表的头引用为null,则单链表为空,返回true,否则返回false。
/// 判断单链表是否为空的算法实现如下
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
if (head == null)
{
return true;
}
return false;
} /// <summary>
/// 附加操作
/// 单链表的附加操作也需要从单链表的头引用开始遍历单链表,直到单链表的末尾,然后在单链表的末端添加一个新结点。
/// </summary>
/// <param name="item"></param>
public bool Append(T item)
{
Node<T> appendItem = new Node<T>(item);
if (IsEmpty())
{
head = appendItem;
}
else
{
Node<T> theLastItem = new Node<T>();
theLastItem = head;
while (theLastItem.Next != null)
{
theLastItem = theLastItem.Next;
}
theLastItem.Next = appendItem;
}
return true;
} /// <summary>
/// 插入操作
/// 单链表的插入操作是指在表的第i个位置结点处插入一个值为item的新结点。插入操作需要从单连表的头引用开始遍历,直到找到第i个位置的结点。插入操作分为在结点之前插入的前插操作和在结点之后插入的后插操作。
/// 注意点:
/// 1插入要考虑空,满
/// 2插入要考虑输入位置是否正确
/// 3要把前继节点给具体显式声明出来,这样比较清晰!
/// 我这里做的是《前插》操作!!!!!!!!
/// </summary>
/// <param name="item"></param>
/// <param name="i"></param>
public void Insert(T item, int i)
{
int len = GetLength();
if (len == 0)
{
Console.WriteLine("单链表为空,不存在插入过程!");
}
else if (i <= 0 || i > len)
{
Console.WriteLine("你输入的位置有错误!!!");
}
else
{
//插头部(这样对于我的逻辑来说清晰一点)
if (i == 1)
{
Node<T> temp = new Node<T>();
temp = head;
head = new Node<T>(item);
head.Next = temp;
}
else
{
Node<T> p = head;
int j = 1;
while (p.Next != null)
{
if (++j == i)
{
//找到了要插入的位置的前面一个节点
Node<T> temp = new Node<T>();
temp = p.Next;
p.Next = new Node<T>(item);
p.Next.Next = temp;
//完成了插入工作,退出循环!
break;
}
p = p.Next;
}
}
}
#region 教科书的前插操作
// 前插操作
//前插操作需要查找第i个位置的结点的直接前驱。设p指向第i个位置的结点,q指向待插入的新结点,r指向p的直接前驱结点,将q插在p之前的操作如图2.8所示。如果要在第一个结点之前插入新结点,则需要把p结点的地址保存在q的引用域中,然后把p的地址保存在头引用中。
// public void Insert(T item, int i)
//{
//if (IsEmpty() || i < 1)
//{
//Console.WriteLine(“List is empty or Position is error!”);
//return;
//}
//if (i == 1)
//{
//Node<T> q = new Node<T>(item);
//q.Next = head;
//head = q;
//return;
//}
//Node<T> p = head;
//Node<T> r = new Node<T>();
//int j = 1;
//while (p.Next != null&& j < i)
//{
//r = p;
//p = p.Next;
//++j;
//}
//if (j == i)
//{
//Node<T> q = new Node<T>(item);
//q.Next = p;
//r.Next = q;
//}
//else
//{
//Console.Writeline(“Position is error!”);
//}
//return;
//} #endregion } /// <summary>
/// 删除操作
/// 单链表的删除操作是指删除第i个结点,返回被删除结点的值。删除操作也需要从头引用开始遍历单链表,直到找到第i个位置的结点。如果i为1,则要删除第一个结点,则需要把该结点的直接后继结点的地址赋给头引用。对于其它结点,由于要删除结点,所以在遍历过程中需要保存被遍历到的结点的直接前驱,找到第i个结点后,把该结点的直接后继作为该结点的直接前驱的直接后继。删除操作如图2.10所示。
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public bool Delete(int i)
{
int len = GetLength();
if (IsEmpty())
{
Console.WriteLine("单链表为空,根本不存在删除操作");
return false;
}
else if (i <= 0 || i > len)
{
Console.WriteLine("输入的位置有误!!!!!");
return false;
}
else
{
if (i == 1)
{
head = head.Next;
}
else
{
Node<T> beforeDelete = new Node<T>();
Node<T> currentNode = new Node<T>();
currentNode = head;
int currentIndex = 1;
while (currentNode.Next != null && currentIndex < i)
{
beforeDelete = currentNode;
currentNode = currentNode.Next;
currentIndex++;
}
//这样写比较有逻辑性一点
//先通过while,找出要删除的节点之前的那一个节点
//while,只负责此逻辑功能
//不像我的《插入》写法,显得比较乱
//这点仁者见仁智者见智
beforeDelete.Next = currentNode.Next;
}
return true;
}
} /// <summary>
/// 取表元
/// 取表元运算是返回单链表中第i个结点的值。与插入操作一样,时间主要消耗在结点的遍历上。如果表为空则不进行遍历。当表非空时,i等于1遍历的结点数最少(1个),i等于n遍历的结点数最多(n个,n为单链表的长度),平均遍历的结点数为n/2。所以,取表元运算的时间复杂度为O(n)。
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public T GetElem(int i)
{
int len = GetLength();
if (IsEmpty())
{
Console.WriteLine("单链表是空的,没什么好取出来!");
return default(T);
}
if (i <= 0 || i > len)
{
Console.WriteLine("你输入的位置有误!");
return default(T);
}
else
{
Node<T> p = head;
int j = 1;
//这种循环的写法
//在单链表的操作中
//尤其常见
while (p.Next != null && j < i)
{
p = p.Next;
j++;
}
return p.Data;
}
} /// <summary>
/// 按值查找
/// 单链表中的按值查找是指在表中查找其值满足给定值的结点。由于单链表的存储空间是非连续的,所以,单链表的按值查找只能从头引用开始遍历,依次将被遍历到的结点的值与给定值比较,如果相等,则返回在单序表中首次出现与给定值相等的数据元素的序号,称为查找成功;否则,在单链表中没有值与给定值匹配的结点,返回一个特殊值表示查找失败。
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public int Locate(T value)
{
bool haveFound = false;
Node<T> p = new Node<T>();
p = head;
int j = 1;
while (p.Next != null)
{
if (p.Data.Equals(value))
{
haveFound = true;
break;
}
p = p.Next;
j++;
}
if (haveFound)
return j;
else
return -1;
#region 教科书错误的写法,如果没有找到,会返回最后一个元素的index
// public int Locate(T value)
//{
//if(IsEmpty())
//{
//Console.WriteLine("List is Empty!");
//return -1;
//}
//Node<T> p = new Node<T>();
//p = head;
//int i = 1;
//while (!p.Data.Equals(value)&& p.Next != null)
//{
// P = p.Next;
//++i;
//}
//return i;
//}
#endregion
}
} public class Node<T>
{ private Node<T> next; public Node<T> Next
{
get { return next; }
set { next = value; }
} private T data; public T Data
{
get { return data; }
set { data = value; }
} public Node(T t)
{
data = t;
next = null;
} public Node()
{
// TODO: Complete member initialization
next = null;
}
}
}
数据结构之单链表,c#实现的更多相关文章
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- javascript数据结构之单链表
下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...
- 数据结构之单链表的实现-java
一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...
- python 数据结构之单链表的实现
链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结点都包含了可以链接起来的地址信息,所以用一个变量就 ...
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
- 数据结构 - 静态单链表的实行(C语言)
静态单链表的实现 1 静态链表定义 静态链表存储结构的定义如下: /* 线性表的静态链表存储结构 */ #define MAXSIZE 1000 /* 假设链表的最大长度是1000 */ typede ...
- 数据结构 - 动态单链表的实行(C语言)
动态单链表的实现 1 单链表存储结构代码描述 若链表没有头结点,则头指针是指向第一个结点的指针. 若链表有头结点,则头指针是指向头结点的指针. 空链表的示意图: 带有头结点的单链表: 不带头结点的单链 ...
- 【数据结构】单链表介绍及leetcode206题反转单链表python实现
题目传送门:https://leetcode-cn.com/problems/reverse-linked-list/ 文章目录 单链表介绍 链表 概念 种类 优缺点 单链表(slist) leetc ...
- 数据结构(2):单链表学习使用java实现
单链表是单向链表,它指向一个位置: 单链表常用使用场景:根据序号排序,然后存储起来. 代码Demo: package com.Exercise.DataStructure_Algorithm.Sing ...
- 数据结构:单链表结构字符串(python版)添加了三个新功能
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
随机推荐
- H264编码技术
H.264的目标应用涵盖了眼下大部分的视频服务,如有线电视远程监控.交互媒体.数字电视.视频会议.视频点播.流媒体服务等.H.264为解决不同应用中的网络传输的差异.定义了两层:视频编码层(VCL:V ...
- linux下单独安装oracle12.1客户端
1.安装oracle-instantclient:(默认安装即可) oracle-instantclient12.1-sqlplus-12.1.0.1.0-1.x86_64.rpmoracle-ins ...
- 【转】Xcode升到6.4插件失效,与添加插件不小心点击Skip Bundle解决办法
转载自:http://www.jianshu.com/p/d51547d29309 今天升级了xcode到6.4 发现之前装的插件不能使用了.这里有一个解决的方案: 步骤如下: 一.查看Xcode的U ...
- TFS 用户与组管理(转)
作者:frank.liu kaka.zhou 安装 Team Foundation Server 后,会创建以下全局组.可以使用这些全局组来控制 Team Foundation 用户的权限. 组 权限 ...
- 整理的sql sever一些数据库查询面试题
当然,我整理的只是一些常见的面试题,具体数据库就不给了,相信大家能看懂!!! --2列出EMPLOYEES表中各部门的部门号,最高工资,最低工资 select Max(salary) as '最高工资 ...
- Oracle自动备份脚本
set mydate=%date:~0,4%%date:~5,2%%date:~8,2%exp 用户名/密码@实例名 file=D:\mydata_%mydate%.dmp owner=用户名 log ...
- PHP上传文件DEMO
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"> <html> <head> ...
- 基于'sessionStorage'与'userData'的类session存储
Storage.js: 注意:此版本实现的存储在符合Web存储标准(ie8及ie8以上的版本与其他主流浏览器)的情况下与session的周期一致,但在页面不关闭的情况下没有过期时间,ie7及以下版本则 ...
- MFC的初始化过程和消息映射技术
1.删除#include <windows.h>--win32中的-(使用win32工程编程mfc必须删除) 添加#include <afxwin.h> -- mfc中的- 2 ...
- php,apache伪静态(1转)
1.检测Apache是否支持mod_rewrite通过php提供的phpinfo()函数查看环境配置,通过Ctrl+F查找到“Loaded Modules”,其中列出了所有apache2handler ...