[作业] 城市链表窗体程序

代码

节点类

class Node
    {
        public string Name;
        public int X, Y;
        public Node Next;
        public Node(string name, int x, int y, Node next)
        {
            Name = name;
            X = x;
            Y = y;
            Next = next;
        }
        public override string ToString()
        {
            return string.Format("{0} 坐标:({1},{2})", Name, X, Y);
        }
    }

这里把城市的属性和节点封装在了一起 并没有使用泛型 因为本题只针对城市一种类型 没有必要
其次是链表类的定义中用到了三种有不同参数的搜索函数 需要访问城市的属性
如果把城市的属性另外封装在一个类中 使用泛型将不好访问类的成员(也许有其他方法规避这个问题)//已解决 可以重载接口中的CompareTo方法
覆写了节点类的Tostring方法 以便接下来在listbox中添加显示

链表主体定义

class Linklist
    {
        int length;
        Node pHead;
        public int Length
        {
            get { return length; }
        }
        public Node this[int index]
        {
            get
            {
                return ElementAt(index);
            }
            set
            {
                ElementAt(index).Name = value.Name;
                ElementAt(index).X = value.X;
                ElementAt(index).Y = value.Y;
            }
        }
        public Linklist()
        {
            length = 0;
            pHead = null;
        }
        public void Indexcheck(int index)
        {
            if (index < 0 || index > length - 1)
                throw new IndexOutOfRangeException();
        }
        #region 查找函数重载
        public int IndexOf(string name)
        {
            int i;
            Node temp = pHead;
            for (i = 0; i < length; i++)
            {
                if (temp.Name.Equals(name))
                    break;
                temp = temp.Next;
            }
            return i == length ? -1 : i;
        }
        public int IndexOf(int x, int y)
        {
            int i;
            Node temp = pHead;
            for (i = 0; i < length; i++)
            {
                if (temp.X == x && temp.Y == y)
                    break;
                temp = temp.Next;
            }
            return i == length ? -1 : i;
        }
        public int IndexOf(string name,int x, int y)
        {
            int i;
            Node temp = pHead;
            for (i = 0; i < length; i++)
            {
                if (temp.X == x && temp.Y == y && temp.Name.Equals(name))
                    break;
                temp = temp.Next;
            }
            return i == length ? -1 : i;
        }
        #endregion
        public Node ElementAt(int index)
        {
            Indexcheck(index);
            Node temp = pHead;
            for (int i = 0; i < index; i++)
            {
                temp = temp.Next;
            }
            return temp;
        }
        public void Insert(Node city, int index) //这里传进来的city.Next=null
        {
            if (length == 0)
            { pHead = city; }
            else
            {
                //Indexcheck(index);
                if (index < 0 || index > length) throw new ArgumentOutOfRangeException();
                if (IndexOf(city.Name) != -1) { throw new Exception("已有同名城市"); }
                if (index == 0)
                {
                    Node temp = pHead;
                    pHead = city;
                    city.Next = temp;
                }
                else if (index == length) { ElementAt(length - 1).Next = city; city.Next = null; } //length++ }
                else
                {
                    city.Next = ElementAt(index);
                    ElementAt(index - 1).Next = city;
                }
            }
            length++;
        }
        public void Clear()
        {
            pHead = null;
            length = 0;
        }
        public bool IsEmpty() { return length == 0; }
        public void Remove(int index)
        {
            if (length == 0) return;
            else if (index == 0) pHead = pHead.Next;
            else if (index == length - 1) ElementAt(index - 1).Next = null;
            else ElementAt(index - 1).Next = ElementAt(index + 1);
            length--;
        }
    }

以上包含了城市链表的各种方法及属性的定义
其中IndexOf方法是搜索方法,用了三种不同的重载类型,分别是查名字、查坐标、查名字+坐标(默认城市名字与坐标都不一样 下有查重但是只查了名字)
Insert方法包括首插和尾插 只需要填写相应的index即可
如果要做窗体程序的话 链表中的各项输入参数的检查应该是不必要的 因为可以在窗体中实现输入参数的检查(可能个别地方仍然需要)

窗体

在这里插入图片描述

public partial class Form1 : Form
    {
        Linklist citylist = new Linklist();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void listBox_refresh()
        {
            CitylistBox.Items.Clear();
            for (int i = 0; i < citylist.Length; i++)
            {
                CitylistBox.Items.Add(citylist[i]);
            }
        }

        private void InsertBtn_Click(object sender, EventArgs e)
        {
            try { int.Parse(CityXTB.Text); int.Parse(CityYTB.Text); int.Parse(InsertIndexTB.Text); }
            catch { MessageBox.Show("输入参数不正确"); return; }
            int index = int.Parse(InsertIndexTB.Text) - 1;
            if (index < 0 || index > citylist.Length) { MessageBox.Show("插入位置超出索引范围"); return; }
            if (citylist.IndexOf(CitynameTB.Text) != -1) { MessageBox.Show("已有同名城市"); return; }
            Node newcity = new Node(CitynameTB.Text, int.Parse(CityXTB.Text), int.Parse(CityYTB.Text), null);
            citylist.Insert(newcity, int.Parse(InsertIndexTB.Text) - 1);
            listBox_refresh();
        }

        private void UpdateBtn_Click(object sender, EventArgs e)
        {
            if (CitylistBox.SelectedIndex == -1)
            {
                MessageBox.Show("未选定城市");
                return;
            }
            try { int.Parse(UpdateCityXTB.Text); int.Parse(UpdateCityYTB.Text); }
            catch { MessageBox.Show("输入参数不正确"); return; }
            //citylist[CitylistBox.SelectedIndex].Name = UpdateCitynameTB.Text;
            //citylist[CitylistBox.SelectedIndex].X = int.Parse(UpdateCityXTB.Text);
            //citylist[CitylistBox.SelectedIndex].Y = int.Parse(UpdateCityYTB.Text);
            citylist[CitylistBox.SelectedIndex] = new Node(UpdateCitynameTB.Text, int.Parse(UpdateCityXTB.Text),
                int.Parse(UpdateCityYTB.Text), citylist[CitylistBox.SelectedIndex].Next);
            listBox_refresh();
        }

        private void SearchBtn_Click(object sender, EventArgs e)
        {
            if (citylist.IndexOf(SearchCitynameTB.Text) != -1)
            {
                Node currentcity = citylist[citylist.IndexOf(SearchCitynameTB.Text)];
                SearchLocation.Text = string.Format("({0},{1})", currentcity.X, currentcity.Y);
            }
            else { MessageBox.Show("未找到所给城市"); SearchLocation.Text = "(,)"; return; }
        }

        private void MatchBtn_Click(object sender, EventArgs e)
        {
            try { double.Parse(MatchDistanceTB.Text); int.Parse(MatchXTB.Text); int.Parse(MatchYTB.Text); }
            catch { MessageBox.Show("输入参数不正确"); return; }
            MatchResult.Text = null;
            List<Node> Resultlist = new List<Node>();
            double distance = 0;
            int x = int.Parse(MatchXTB.Text), y = int.Parse(MatchXTB.Text);
            for (int i = 0; i < citylist.Length; i++)
            {
                distance = Math.Sqrt((citylist[i].X - x) * (citylist[i].X - x) + (citylist[i].Y - y) * (citylist[i].Y - y));
                if (distance < double.Parse(MatchDistanceTB.Text))
                    Resultlist.Add(citylist[i]);
            }
            if (Resultlist.Count != 0)
            {
                foreach (Node city in Resultlist)
                {
                    MatchResult.Text += (city.Name + '\n');
                }
            }
            else
                MatchResult.Text = "无";
        }

        private void DeleteBtn_Click(object sender, EventArgs e)
        {
            if (CitylistBox.SelectedIndex != -1)
            {
                citylist.Remove(CitylistBox.SelectedIndex);
                listBox_refresh();
            }
            else
            {
                MessageBox.Show("未选定城市");
                return;
            }
        }
    }

窗体部分代码 包括各项输入参数的检查
listbox_refresh方法用于城市链表修改以后更新listbox中的显示
使用此方法资源浪费很大 会执行许多不必要的语句 但是省事
更正确节约的方法应该是每处对链表进行修改后对listbox也做出相应的修改 不需要整体全部刷新

运行效果:
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值