数据结构02-单链表(用C++、C#、lua实现)
本文为数据结构-单链表的代码实现。
作者水平比较差,有错误的地方请见谅。
1、C#实现
线性表接口
IListDS.cs
/// <summary>
/// 线性表接口
/// </summary>
interface IListDS<T>
{
int GetLength(); //求表长度
void Clear(); //清空
bool IsEmpty(); //判断表是否为空
void Add(T item); //添加
void Insert(T item, int index); //插入
T PriorElem(int index); //求前驱
T NextElem(int index); //求后继
T Delete(int index); //删除
T GetElem(int index); //取表元素
T this[int index] { get; }//根据索引器 获取表中元素
int Locate(T value); //按值查找,返回值下标
void ShowAllElem(); //显示所有元素
}
单链表结点类
Node.cs
/// <summary>
/// 单链表的结点
/// 一个结点中包括数据和下一个结点的指针
/// </summary>
class Node<T>
{
private T mData;
private Node<T> mNext;
public T Data { get { return mData; } set { mData = value; } }
public Node<T> Next { get { return mNext; } set { mNext = value; } }
public Node()
{
mData = default(T);
mNext = null;
}
public Node(T data)
{
mData = data;
}
public Node(T data, Node<T> next)
{
mData = data;
mNext = next;
}
public Node(Node<T> next)
{
mNext = next;
}
}
单链表类
LinkList.cs
/// <summary>
/// 单链表
/// </summary>
class LinkList<T> : IListDS<T>
{
/// <summary>
/// 头结点
/// 头结点只有next没有data
/// </summary>
private Node<T> mHead;
public LinkList()
{
mHead = new Node<T>();
}
~LinkList()
{
//销毁头结点
mHead = null;
}
public bool IsEmpty()
{
return mHead.Next==null;
}
public int GetLength()
{
int length = 0;
Node<T> temp = mHead.Next;
while (temp != null)
{
length++;
temp = temp.Next;
}
return length;
}
public T GetElem(int index)
{
T data = default(T);
if (index >= 0 && index <= GetLength()-1)
{
Node<T> temp = mHead.Next;
for (int i = 0; i < index; i++)
{
temp = temp.Next;
}
data = temp.Data;
}
else
{
Console.WriteLine("index的范围有误。");
}
return data;
}
public int Locate(T value)
{
Node<T> temp = mHead.Next;
int count = 0;
while (temp.Next != null)
{
if (temp.Data.Equals(value))
{
return count;
}
count++;
temp = temp.Next;
}
Console.WriteLine(value + "在单链表中不存在。");
return -1;
}
public T this[int index]
{
get
{
return GetElem(index);
}
}
public void Add(T item)
{
Node<T> node = new Node<T>(item);
if (mHead.Next == null)
{
mHead.Next = node;
}
else
{
//获取到最后一个结点
Node<T> temp = mHead.Next;
while (temp.Next != null)
{
temp = temp.Next;
}
temp.Next = node;
}
}
public void Insert(T item, int index)
{
//把插入的新结点重新设置为第一个结点
if (index == 0)
{
Node<T> newNode = new Node<T>(item, mHead.Next);
mHead.Next = newNode;
}
else if(index > 0 && index <= GetLength())
{
Node<T> temp = mHead.Next;
for (int i = 0; i < index-1; i++)
{
temp = temp.Next;
}
//此时temp为应插入位置的前一个结点
Node<T> newNode = new Node<T>(item, temp.Next);
temp.Next = newNode;
}
else
{
Console.WriteLine("要插入的范围有误。");
}
}
public T Delete(int index)
{
T data = default(T);
//删除第一个结点
if (index == 0)
{
data = mHead.Next.Data;
mHead.Next = mHead.Next.Next;
}
else if (index > 0 && index <= GetLength() - 1)
{
Node<T> frontDelete = mHead.Next;
for (int i = 0; i < index - 1; i++)
{
frontDelete = frontDelete.Next;
}
Node<T> delete = frontDelete.Next;
frontDelete.Next = delete.Next;
data = delete.Data;
}
else
{
Console.WriteLine("要删除的范围有误。");
}
return data;
}
public void Clear()
{
mHead.Next = null;
}
public T PriorElem(int index)
{
T data = default(T);
if (index == 0)
{
Console.WriteLine("第一个结点无前驱。");
}
else if (index > 0 && index <= GetLength() - 1)
{
Node<T> prior = mHead.Next;
for (int i = 0; i < index - 1; i++)
{
prior = prior.Next;
}
data = prior.Data;
}
else
{
Console.WriteLine("index的范围有误。");
}
return data;
}
public T NextElem(int index)
{
T data = default(T);
if (index == GetLength() - 1)
{
Console.WriteLine("最后一个结点无后继。");
}
else if (index >= 0 && index < GetLength() - 1)
{
Node<T> next = mHead.Next;
for (int i = 0; i < index+1; i++)
{
next = next.Next;
}
data = next.Data;
}
else
{
Console.WriteLine("index的范围有误。");
}
return data;
}
public void ShowAllElem()
{
Node<T> temp = mHead.Next;
int count = 0;
while (temp != null)
{
Console.WriteLine(string.Format("第{0}个结点值为:{1}。", count++, temp.Data));
temp = temp.Next;
}
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
#region 单链表
IListDS<string> strLinkList = new LinkList<string>();
strLinkList.Add("111");
strLinkList.Add("222");
strLinkList.Add("333");
strLinkList.Add("444");
//测试
//Console.WriteLine(strLinkList.IsEmpty());
//Console.WriteLine(strLinkList.GetLength());
//Console.WriteLine(strLinkList.GetElem(0));
//Console.WriteLine(strLinkList.Locate("222"));
//Console.WriteLine(strLinkList[2]);
//strLinkList.Insert("aaa", 2);
//strLinkList.Delete(2);
//Console.WriteLine(strLinkList.PriorElem(2));
//Console.WriteLine(strLinkList.NextElem(2));
strLinkList.ShowAllElem();
#endregion
Console.ReadKey();
}
}
2、C++实现
线性表接口
IList.cpp
#include <iostream>
using namespace std;
typedef int ElemType;
class IList
{
public:
///清空
virtual void Clear() = 0;
///是否为空
virtual bool IsEmpty() = 0;
///长度
virtual int GetLength() = 0;
///根据下标取表元素
virtual ElemType GetElem(int index) = 0;
///返回相同元素的位置
virtual int LocateElem(ElemType value) = 0;
///求前驱
virtual ElemType PriorElem(int index) = 0;
///求后继
virtual ElemType NextElem(int index) = 0;
///添加元素
virtual void Add(ElemType value) = 0;
///插入元素
virtual void Insert(ElemType value,int index) = 0;
///删除元素
virtual void Delete(int index) = 0;
///显示线性表中元素
virtual void ShowAllList() = 0;
};
单链表
LinkList.cpp
#include <iostream>
#include "IList.cpp"
using namespace std;
typedef int ElemType;
///结点
typedef struct LNode
{
ElemType data;
struct LNode * next;
}LNode , *LinkNode;
class LinkList:public IList
{
private:
//头结点
//头结点只有next无data
LinkNode headNode;
public:
///顺序表初始化
LinkList();
///顺序表销毁
~LinkList();
void Clear();
bool IsEmpty();
int GetLength();
ElemType GetElem(int index);
int LocateElem(ElemType value);
ElemType PriorElem(int index);
ElemType NextElem(int index);
void Add(ElemType value);
void Insert(ElemType value,int index);
void Delete(int index);
void ShowAllList();
};
LinkList::LinkList()
{
headNode = new LNode();
headNode->next = NULL;
}
LinkList::~LinkList()
{
LinkNode temp;
while(headNode != NULL){
temp = headNode;
headNode = headNode->next;
delete temp;
}
}
bool LinkList::IsEmpty()
{
return headNode == NULL;
}
int LinkList::GetLength()
{
int length = 0;
LinkNode temp = headNode->next;
while(temp != NULL){
temp = temp->next;
length++;
}
return length;
}
ElemType LinkList::GetElem(int index)
{
ElemType data;
if (index >= 0 && index <= GetLength()-1)
{
LinkNode temp = headNode->next;
for (int i = 0; i < index; i++)
{
temp = temp->next;
}
data = temp->data;
}
else
{
cout<<"index的范围有误。"<<endl;
}
return data;
}
void LinkList::Clear()
{
LinkNode temp;
LinkNode temp2 = headNode->next;
while(temp2 != NULL){
temp = temp2;
temp2 = temp2->next;
delete temp;
}
headNode->next = NULL;
}
int LinkList::LocateElem(ElemType value)
{
LinkNode temp = headNode->next;
int num = 0;
while (temp->next != NULL)
{
if (temp->data == value)
{
return num;
}
num++;
temp = temp->next;
}
cout<<value<<"在单链表中不存在。"<<endl;
return -1;
}
ElemType LinkList::PriorElem(int index)
{
ElemType data;
if (index == 0)
{
cout<<"第一个结点无前驱。"<<endl;
}
else if(index > 0 && index <= GetLength()-1)
{
LinkNode prior = headNode->next;
for (int i = 0; i < index-1; i++)
{
prior = prior->next;
}
data = prior->data;
}
else
{
cout<<"index的范围有误。"<<endl;
}
return data;
}
ElemType LinkList::NextElem(int index)
{
ElemType data;
if (index == GetLength() - 1)
{
cout<<"最后一个结点无后继。"<<endl;
}
else if(index >= 0 && index < GetLength()-1)
{
LinkNode next = headNode->next;
for (int i = 0; i < index+1; i++)
{
next = next->next;
}
data = next->data;
}
else
{
cout<<"index的范围有误。"<<endl;
}
return data;
}
void LinkList::Add(ElemType value)
{
LinkNode node = new LNode();
node->data = value;
if(headNode->next != NULL){
LinkNode temp = headNode->next;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = node;
}
else{
headNode->next = node;
}
}
void LinkList::Insert(ElemType value,int index)
{
if (index == 0)
{
//把插入的新结点设置为第一个结点
LinkNode newNode = new LNode();
newNode->data = value;
newNode->next = headNode->next;
headNode->next = newNode;
}
else if(index > 0 && index <= GetLength())
{
LinkNode temp = headNode->next;
for (int i = 0; i < index-1; i++)
{
temp = temp->next;
}
//此时temp为应插入位置的前一个结点
LinkNode newNode = new LNode();
newNode->data = value;
newNode->next = temp->next;
temp->next = newNode;
}
else
{
cout<<"要插入的范围有误。"<<endl;
}
}
void LinkList::Delete(int index)
{
ElemType data;
//删除第一个结点
if (index == 0)
{
data = headNode->next->data;
headNode->next = headNode->next->next;
}
else if (index > 0 && index <= GetLength() - 1)
{
LinkNode frontDelete = headNode->next;
for (int i = 0; i < index - 1; i++)
{
frontDelete = frontDelete->next;
}
LinkNode del = frontDelete->next;
frontDelete->next = del->next;
data = del->data;
}
else
{
cout<<"要删除的范围有误。"<<endl;
}
}
void LinkList::ShowAllList()
{
LinkNode temp = headNode->next;
int num = 0;
while(temp != NULL){
cout<<"第"<<num++<<"个结点值为:"<<temp->data<<endl;
temp = temp->next;
}
}
main.cpp
#include <iostream>
#include "LinkList.cpp"
using namespace std;
int main()
{
LinkList l;
l.Add(111);
l.Add(222);
l.Add(333);
l.Add(444);
//cout<<l.IsEmpty()<<endl;
//cout<<l.GetLength()<<endl;
//cout<<l.GetElem(2)<<endl;
l.Clear();
l.Add(111);
l.Add(222);
l.Add(333);
l.Add(444);
//cout<<l.LocateElem(222)<<endl;
//cout<<l.PriorElem(3)<<endl;
//cout<<l.NextElem(2)<<endl;
//l.Insert(999,2);
//l.Delete(1);
l.ShowAllList();
return 0;
}
3、lua实现
--linkList也相当于头结点
linkList = {}
--初始化
function linkList:Init()
--初始化头结点
self.data = 0
self.next = nil
end
--销毁
function linkList:Destory()
self:Clear()
self = nil
end
--清空
function linkList:Clear()
--销毁头结点后的所有结点
while(self.next) do
local temp = self.next
temp = temp.next
self.next = nil
self.next = temp
end
end
--长度
function linkList:GetLength()
local temp = self.next
local length = 0
while(temp) do
length = length + 1
temp = temp.next
end
return length
end
--添加元素
function linkList:Add(value)
--要添加的结点
local node = {data = value,next = nil}
local temp = self
if(temp.next) then
while(temp.next) do
temp = temp.next
end
temp.next = node
else
temp.next = node
end
end
--取表元素
function linkList:GetElem(index)
local data = nil
if (index >= 0 and index <= self:GetLength()-1) then
local temp = self.next
for i=0,index-1,1 do
temp = temp.next
end
data = temp.data
else
print("index的范围有误。")
end
return data
end
--按值查找,返回下标
function linkList:Locate(value)
local temp = self.next
local count = 0;
while (temp.next ~= nil) do
if (temp.data == value) then
return count
end
count = count + 1
temp = temp.next
end
print(value .. "在单链表中不存在。")
end
--前驱
function linkList:PriorElem(index)
local data = nil
if (index == 0) then
print("第一个结点无前驱。")
elseif (index > 0 and index <= self:GetLength() - 1) then
local prior = self.next
for i=0,index-2,1 do
prior = prior.next
end
data = prior.data
else
print("index的范围有误。")
end
return data
end
--后继
function linkList:NextElem(index)
local data = nil
if (index == self:GetLength() - 1) then
print("最后一个结点无后继。")
elseif (index >= 0 and index < self:GetLength() - 1) then
local next = self.next
for i=0,index,1 do
next = next.next
end
data = next.data;
else
print("index的范围有误。")
end
return data
end
--插入
function linkList:Insert(value,index)
if (index == 0) then
--把插入的新结点设置为第一个结点
local newNode = {}
newNode.data = value
newNode.next = self.next
self.next = newNode
elseif(index > 0 and index <= self:GetLength()) then
local temp = self.next
for i=0,index-2,1 do
temp = temp.next
end
--此时temp为应插入位置的前一个结点
local newNode = {}
newNode.data = value
newNode.next = temp.next
temp.next = newNode
else
print("要插入的范围有误。")
end
end
--删除
function linkList:Delete(index)
local data
--删除第一个结点
if (index == 0) then
data = self.next.data
self.next = self.next.next
elseif (index > 0 and index <= self:GetLength() - 1) then
--要删除结点的前一个
local frontDelete = self.next
for i=0,index-2,1 do
frontDelete = frontDelete.next
end
--要删除的结点
local del = frontDelete.next
frontDelete.next = del.next
data = del.data
else
print("要删除的范围有误。")
end
end
--显示所有元素
function linkList:ShowAllElem()
local temp = linkList.next
local num = 0
while(temp) do
print("第" .. num .. "个元素为:" .. temp.data)
temp = temp.next
num = num + 1
end
end
--主运行函数
function main()
linkList:Init()
linkList:Add(111)
linkList:Add(222)
linkList:Add(333)
linkList:Add(444)
linkList:Clear()
linkList:Add(111)
linkList:Add(222)
linkList:Add(333)
linkList:Add(444)
--print(linkList:GetLength())
--print(linkList:GetElem(2))
--print(linkList:Locate(2))
--print(linkList:Locate(222))
--print(linkList:PriorElem(2))
--print(linkList:NextElem(2))
--linkList:Insert("aaa",2)
--linkList:Delete(2)
linkList:ShowAllElem()
end
main()