博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决线性表的编程问题
阅读量:5118 次
发布时间:2019-06-13

本文共 23943 字,大约阅读时间需要 79 分钟。

一、定义相关

1、线性表:由n个相同的类型的数据元素组成的有限的序列。

    特点:(1)有且仅有一个开始结点,没有直接前趋,仅有一个后继结点。

     (2)有且仅有一个终端结点,没有直接后继,仅有一个直接前驱。

    分类:顺序表、单链表、双链表、循环链表

    操作:

interface IlinarList
{ void InsertNode(T a,int i);//插入操作 void DeleteNode(int i);//删除操作 T SearchNode(int i);//查找表元素 T SearchNode(T value);//定位表元素 int GetLength();//求取表长度 void Clear();//清空操作 bool IsEmpty();//判断线性表是否为空 }

二、代码分析

1、顺序表

//用顺序链表解决    public class SeqList
:IlinarList
{ private int maxsize;//顺序表的最大容量 private T[] data;//定义一个用于存储数据元素的数组 private int length;//顺序表的实际长度 public int Maxsize{ get { return maxsize; } set { maxsize = value; } } public int Length { get { return length; } set { length = value; } } //初始化线性表 public SeqList(int size) { maxsize = size; data=new T[maxsize]; length = 0; } //判断顺序表是否为满 public bool IsFull() { if (length==maxsize) { return true; } else { return false; } } //判断顺序表是否为空 public bool IsEmpty() { if (length==0) { return true; } else { return false; } } //清空操作 public void Clear() { length = 0; } //求取顺序表的长度 public int GetLength() { return length; } //在顺序表的末尾添加元素 public void InsertNode(T a) { if (IsFull()==true) { Console.WriteLine("List is full"); return; } data[length] = a; length = length + 1; } //在顺序表的第i个位置插入一个数据元素 public void InsertNode(T a, int i) { if (IsFull() == true) { Console.WriteLine("List is full"); return; } if (i < 1 || i > length+1) { Console.WriteLine("Position is error"); return; } else { data[i - 1] = a; for (int j = i; j < length;j++ ) { data[j+1] = data[j ]; } } length++; } //删除顺序表中的第i个元素 public void DeleteNode(int i) { if (IsEmpty() == true) { Console.WriteLine("List is empty ."); return; } if (i < 1 || i > length) { Console.WriteLine("Position is error"); return; } for (int j = i ; j < length; j++) { data[j-1] = data[j]; } length--; } //获得顺序表中的第i个元素 public T SearchNode(int i) { if (IsEmpty() == true || i < 1 || i > length) { Console.WriteLine("List is empty or position is error !"); return default(T); } return data[i-1]; } //在顺序表中查找值为value的数据元素 public T SearchNode(T a) { if (IsEmpty() == true) { Console.WriteLine("List is empty !"); return default(T); } int i = 0; for ( i = 0; i < length; i++) { if (data[i].ToString().Equals(a.ToString())) { break; } } if(i>length) { return default(T); } return data[i]; } }
View Code

2、单链表

class SLinkList
:IlinarList
{ private SNode
start; int length; public SLinkList() { start = null; } public bool IsEmpty() { if (start == null) { return true; } else { return false; } } public int GetLength() { return length; } public void Clear() { start = null; } public void InsertNode(T a) { if (start == null) { start=new SNode
(a); length++; return; } SNode
current = start; while (current.Next != null) { current = current.Next; } current.Next = new SNode
(a); length++; } //在单链表的第i个位置前插入一个数据元素 public void InsertNode(T a, int i) { SNode
current; SNode
previous; if (i < 1 || i > length + 1) { Console.WriteLine("Position is error !"); return; } SNode
newNodee=new SNode
(a); //在空链表或者链表的第一个位置插入第一个元素 if (i == 1) { newNodee.Next = start; start = newNodee; length++; return; } //在单链表的两个元素之间插入一个元素 current = start; previous = null; int j = 1; while (current != null && j < i) { previous = current; current = current.Next; j++; } if (j == i) { previous.Next = newNodee; newNodee.Next = current; length++; } } //删除单链表的第i个元素 public void DeleteNode(int i) { if (IsEmpty() || i < 1||i>length+1) { Console.WriteLine("SLinkList is empty or position is error !"); } SNode
current = start; if (i == 1) { start = current.Next; length--; return; } SNode
previous = null; int j = 1; while (current.Next != null && j < i) { previous = current; current = current.Next; j++; } if (i == j) { previous.Next = current.Next; current = null; length--; } else { Console.WriteLine("the ith node is not exist !"); } } public T SearchNode(int i) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } SNode
current = start; int j = 1; while (current.Next != null && j < i) { current = current.Next; j++; } if (j == i) { return current.Data; } else { Console.WriteLine("This ith node is not exit !"); return default(T); } } public T SearchNode(T value) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } SNode
current = start; int i = 1; while (!current.Data.ToString().Contains((value.ToString())) && current != null) { current = current.Next; i++; } if (current != null) { return current.Data; } else { return default(T); } } }
View Code

3、双链表

class DLinkList
:IlinarList
{ private DbNode
start; private int length; public DLinkList() { start = null; } public bool IsEmpty() { if (start == null) { return true; } else { return false; } } public void Clear() { start = null; } public int GetLength() { return length; } //在双向链表的末尾追加数据元素 public void InsertNode(T a) { DbNode
newnode=new DbNode
(a); if (IsEmpty()) { start = newnode; length++; return; } DbNode
current = start; while (current.Next != null) { current = current.Next; } current.Next = newnode; newnode.Prev = current; newnode.Next = null; length++; } //在双向链表的第i个数据元素的位置前插入一个数据元素 public void InsertNode(T a, int i) { DbNode
current; DbNode
previous; if (i < 1) { Console.WriteLine("Position is erroe !"); return; } DbNode
newNode=new DbNode
(a); //如果这个位置是第一个位置 if (i == 1) { newNode.Next = start; start = newNode; length++; return; } //在双向链表的两个元素间插入一个元素 current = start; previous = null; int j = 1; while (current != null && j < i) { previous = current; current = current.Next; j++; } if (j == i) { newNode.Next = current; newNode.Prev = previous; if(current!=null) current.Prev = newNode; previous.Next = newNode; length++; } } //删除双向链表的第i个数据元素 public void DeleteNode(int i) { if (IsEmpty() || i < 1) { Console.WriteLine("Link is empty or position is error !"); } DbNode
current = start; if (i == 1) { start = current.Next; length--; return; } DbNode
previous = null; int j = 1; while (current.Next != null && j < i) { previous = current; current = current.Next; j++; } if (j == i) { previous.Next = current.Next; if (current.Next != null) { current.Next.Prev = previous; previous = null; current = null; length--; } } else { Console.WriteLine("The ith node is not exist !"); } } //获取双向链表中查找第i个数据元素 public T SearchNode(int i) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } DbNode
current = start; int j = 1; while (current.Next != null && j < i) { current = current.Next; j++; } if (j == i) { return current.Data; } else { Console.WriteLine("The ith node is not exist !"); return default(T); } } //在双向链表中查找值为value的数据元素 public T SearchNode(T value) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } DbNode
current = start; int i = 1; while (!current.Data.ToString().Contains(value.ToString()) && current != null) { current = current.Next; i++; } if (current != null) { return current.Data; } else { return default(T); } } }
View Code

4、循环链表

class ClinkList
:IlinarList
{ private ClinkNode
start; int length; public ClinkList() { start = null; } public bool IsEmpty() { if (start == null) { return true; } else { return false; } } public int GetLength() { return length; } public void Clear() { start = null; } //在循环链表的末尾追加数据元素 public void InsertNode(T a) { if (start == null) { start=new ClinkNode
(a); length++; return; } ClinkNode
current = start; while (current.Next != null) { current = current.Next; } ClinkNode
temp=new ClinkNode
(a); current.Next = temp; temp.Next = start; length++; } //在单链表的第i个位置前插入一个数据元素 public void InsertNode(T a, int i) { ClinkNode
current; ClinkNode
previous; if (i < 1 || i > length + 1) { Console.WriteLine("Position is error !"); return; } ClinkNode
newNodee = new ClinkNode
(a); //在空链表或者链表的第一个位置插入第一个元素 if (i == 1) { newNodee.Next = start; start = newNodee; length++; return; } //在单链表的两个元素之间插入一个元素 current = start; previous = null; int j = 1; while (current != null && j < i) { previous = current; current = current.Next; j++; } if (j == i) { previous.Next = newNodee; newNodee.Next = current; length++; } } //删除单链表的第i个元素 public void DeleteNode(int i) { if (IsEmpty() || i < 1||i>length+1) { Console.WriteLine("SLinkList is empty or position is error !"); } ClinkNode
current = start; if (i == 1) { start = current.Next; length--; return; } ClinkNode
previous = null; int j = 1; while (current.Next != null && j < i) { previous = current; current = current.Next; j++; } if (i == j) { previous.Next = current.Next; current = null; length--; } else { Console.WriteLine("the ith node is not exist !"); } } public T SearchNode(int i) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } ClinkNode
current = start; int j = 1; while (current.Next != null && j < i) { current = current.Next; j++; } if (j == i) { return current.Data; } else { Console.WriteLine("This ith node is not exit !"); return default(T); } } public T SearchNode(T value) { if (IsEmpty()) { Console.WriteLine("List is empty !"); return default(T); } ClinkNode
current = start; int i = 1; while (!current.Data.ToString().Contains((value.ToString())) && current != null) { current = current.Next; i++; } if (current != null) { return current.Data; } else { return default(T); } } }
View Code

三、应用:在学生成绩表中的应用

1、顺序表

class SNode
{ private T data;//数据域 private SNode
next;//引用域 public SNode(T value, SNode
p) { data = value; next = p; } public SNode(SNode
p) { next = p; } public SNode(T value) { data = value; } public T Data { get { return data; } set { data = value; } } public SNode
Next { get { return next; } set { next = value; } } }
View Code

2、单链表

class ClinkNode
{ private T data;//数据域 private ClinkNode
next;//引用域 public ClinkNode(T value, ClinkNode
p) { data = value; next = p; } public ClinkNode(ClinkNode
p) { next = p; } public ClinkNode(T value) { data = value; } public T Data { get { return data; } set { data = value; } } public ClinkNode
Next { get { return next; } set { next = value; } } }
View Code

3、双链表

class DbNode
{ private T data;//数据域 private DbNode
prev;//前驱引用域 private DbNode
next;//后驱引用域 //构造器 public DbNode(T val, DbNode
p) { data = val; next = p; } public DbNode(DbNode
p) { next = p; } public DbNode(T val) { data = val; next = null; } public DbNode() { data = default(T); next = null; } public T Data { get { return data; } set { data = value; } } public DbNode
Prev { get { return prev; } set { prev = value; } } public DbNode
Next { get { return next; } set { next = value; } } }
View Code

4、循环链表

class ClinkNode
{ private T data;//数据域 private ClinkNode
next;//引用域 public ClinkNode(T value, ClinkNode
p) { data = value; next = p; } public ClinkNode(ClinkNode
p) { next = p; } public ClinkNode(T value) { data = value; } public T Data { get { return data; } set { data = value; } } public ClinkNode
Next { get { return next; } set { next = value; } } }
View Code

5、学生成绩表类

class StuNode    {        private string _stu_no;        private string _stu_name;        private int _stu_score;        public string Stu_no        {            get { return _stu_no; }            set { _stu_no = value; }        }        public string Stu_name        {            get { return _stu_name; }            set { _stu_name = value; }        }        public int Stu_score        {            get { return _stu_score; }            set { _stu_score = value; }        }        public StuNode(string stuNo, string stuName, int stuScore)        {            this._stu_no = stuNo;            this._stu_name = stuName;            this._stu_score = stuScore;        }        public override string ToString()        {            return _stu_no + _stu_name;        }    }
View Code

应用:

private static void Main(string[] args)        {            IlinarList
stuList = null; //SeqList
stuList = null; #region 选择存储结构类型 Console.WriteLine("请选择存储结构的类型:1、顺序表,2、单链表,3、双链表,4、循环链表"); char selectFlag = Convert.ToChar(Console.ReadLine()); switch (selectFlag) { case '1': Console.WriteLine("请输入学生的个数"); int maxsize = Convert.ToInt32(Console.ReadLine()); stuList = new SeqList
(maxsize); break; case '2': stuList=new SLinkList
(); break; case '3': stuList=new DLinkList
(); break; case '4': stuList=new ClinkList
(); break; } #endregion while (true) { Console.WriteLine("请输入操作选项:"); Console.WriteLine("1、添加学生成绩"); Console.WriteLine("2、删除学生成绩"); Console.WriteLine("3、按姓名查询学生成绩"); Console.WriteLine("4、按学号查询学生成绩"); Console.WriteLine("5、查看学生全部信息"); Console.WriteLine("6、退出"); selectFlag = Convert.ToChar(Console.ReadLine()); switch (selectFlag) { #region 添加学生成绩 case '1': { char falg; do { string stuNo; string stuName; int stuScore; Console.WriteLine("请输入学号"); stuNo = Console.ReadLine(); Console.WriteLine("请输入姓名"); stuName = Console.ReadLine(); Console.WriteLine("请输入成绩"); stuScore = Convert.ToInt32(Console.ReadLine()); StuNode newStuNode = new StuNode(stuNo, stuName, stuScore); //添加到首部 if (stuList.GetLength() == 0) { stuList.InsertNode(newStuNode,1); } //添加到尾部 else if (newStuNode.Stu_score > stuList.SearchNode(stuList.GetLength()).Stu_score) { stuList.InsertNode(newStuNode, stuList.GetLength() + 1); } else { for (int i = 1; i <= stuList.GetLength(); i++) { if (newStuNode.Stu_score <= (stuList.SearchNode(i).Stu_score)) { stuList.InsertNode(newStuNode, i); break; } } } Console.WriteLine("还有学生成绩输入吗?(Y/N)"); falg = Convert.ToChar(Console.ReadLine()); } while (falg == 'Y'); break; }#endregion #region 删除学生成绩 case '2': { StuNode temp; Console.WriteLine("请输入要删除的学生的学号:"); string stuNo = Console.ReadLine(); for (int i = 1; i <= stuList.GetLength(); i++) { temp = stuList.SearchNode(i); if (temp.Stu_no == stuNo) { stuList.DeleteNode(i); break; } } break; } #endregion #region 按姓名查询成绩 case '3': { StuNode temp; Console.WriteLine("请输入你要查询学生的姓名"); string stuName = Console.ReadLine(); for (int i = 1; i <= stuList.GetLength(); i++) { temp = stuList.SearchNode(i); if (temp.Stu_name == stuName) { Console.WriteLine("姓名为{0}的成绩是{1}",stuName,temp.Stu_score); break; } } break; } #endregion #region 按学号查询成绩 case '4': { StuNode temp; Console.WriteLine("请输入要查找的学生的学号"); string stuNo = Console.ReadLine(); for (int i = 1; i < stuList.GetLength(); i++) { temp = stuList.SearchNode(i); if (temp.Stu_no == stuNo) { Console.WriteLine("学号为{0}的成绩是{1}",stuNo,temp.Stu_score); break; } } break; } #endregion #region 查看全部学生信息 case '5': { StuNode temp; for (int i = 1; i <= stuList.GetLength(); i++) { temp = stuList.SearchNode(i); Console.WriteLine("\t{0}\t{1}\t{2}",temp.Stu_no,temp.Stu_name,temp.Stu_score); } break; } #endregion #region 退出 case '6': { return; } #endregion } Console.WriteLine("按任意键退出......"); Console.ReadKey(); } } }

四、实际应用

问题描述:

约瑟夫问题的一种描述是:编号为1、2....n的n个人按顺时针方向围座一圈,每人拿一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向从1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列。设计一个程序求出出列顺序。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 循环链表实现约瑟夫环问题{    internal class Program    {        public static int NodeLength = 1; //记录循环链表的长度,同时也是链表节点的序号        public static int markNum = 0; //链表节点的序号        private static void Main(string[] args)        {            Console.WriteLine("请输入节点的值(以-1作为输入的结束):");            int ConsoleRead = Convert.ToInt32(Console.ReadLine()); //接受用户输入的数据,作为第一个节点            Node CircleNode = new Node(ConsoleRead, NodeLength); //构造一个新节点            CircleNode.Next = CircleNode; //将第一个节点的尾部指针指向该节点自身            Node cursor = CircleNode; //设置一个指针            Console.WriteLine("请输入节点的值(以-1作为输入的结束):");            int input = Convert.ToInt32(Console.ReadLine());            while (input != -1) //以-1作为输入的终结            {                NodeLength++; //每增加一个新节点,链表长度加1                 Node nd = new Node(input, NodeLength);                nd.Next = cursor.Next; //将新节点加在链表指针的后面                cursor.Next = nd; //插入新的节点,形成循环链表                cursor = cursor.Next; //将指针后移动一位                Console.WriteLine("请输入节点的值(以-1作为输入的结束):");                input = Convert.ToInt32(Console.ReadLine());            }            //调用函数处理节点的删除            DeleteElem(2, NodeLength, CircleNode);            Console.ReadKey();        }        //处理节点的删除的函数        public static void DeleteElem(int num, int Length, Node nd)        {            #region            int DelData = 0; //删除的节点的数据域的值             if (Length == 0) //链表的长度为0说明节点已经删完,返回            {                return;            }            int position = num%Length; //要删除的节点的位置            if (Length == 1) //删除最后一个节点            {                DelData = nd.data; //删除节点的值                Console.WriteLine("删除的节点的序号:{0}; 删除的节点的数据域的值:{1}", nd.mark, DelData.ToString());                return;            }            Node q = nd;            Node p = q; //设置两个指针节点            //寻找要删除的节点            int i = 1;            while (q.Next != q && i < position && q != null)            {                p = q;                q = q.Next;                i++;            }            #endregion            #region            if (q.Next != q && q.Next != null)            {                if (Length <= 2 && position == 1) //剩下两个元素                {                    DelData = p.data;                    markNum = p.mark;                    q = q.Next;                    q.Next = p.Next;                }                else if (Length <= 2 && position == 0)                {                    q = q.Next;                    DelData = q.data;                    markNum = q.mark;                    p.Next = q.Next;                }                else if (p == q && Length > 2) //节点数目多于两个,并且p,q指针指向同一个节点                {                    if (position == 0)                    {                        q = q.Next;                        while (q.Next.Next != p)                        {                            q = q.Next;                        }                        DelData = q.Next.data;                        markNum = q.Next.mark;                        q.Next = q.Next.Next;                    }                    else                    {                        DelData = p.data;                        markNum = p.mark;                        while (q.Next != null && q.Next != p)                        {                            q = q.Next;                        }                        q.Next = p.Next;                    }                }                else                {                    DelData = q.data;                    markNum = q.mark;                    p.Next = q.Next;                }            }            else            {                DelData = q.data;                markNum = q.mark;            }            #endregion            nd = q.Next;            Length--;            Console.WriteLine("删除的节点的序号:{0}; 删除的节点的数据域的值:{1}", markNum, DelData.ToString());            //递归调用            DeleteElem(DelData, Length, nd);        }    }    class Node//将节点的结构封装成一个类    {        public int data;//数据域        public Node Next;//指针域        public int mark;//节点的标号(以节点入链表的顺序来标志)        public Node(int val,int markVal)//声明一个新的节点        {            data = val;            Next = null;            mark = markVal;        }    }}

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/chenyongblog/p/3227150.html

你可能感兴趣的文章
mysql基础语句
查看>>
cassandra vs mongo (1)存储引擎
查看>>
Visual Studio基于CMake配置opencv1.0.0、opencv2.2
查看>>
MySQL索引背后的数据结构及算法原理
查看>>
#Leetcode# 209. Minimum Size Subarray Sum
查看>>
SDN第四次作业
查看>>
DM8168 DVRRDK软件框架研究
查看>>
django迁移数据库错误
查看>>
yii 跳转页面
查看>>
洛谷 1449——后缀表达式(线性数据结构)
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>
证件照(1寸2寸)拍摄处理知识汇总
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>
Python入门-函数
查看>>