数据结构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()


posted @ 2019-11-03 15:17  Fflyqaq  阅读(226)  评论(0编辑  收藏  举报