C#数据结构与算法学习笔记 有序数组和二分查找

这篇博客探讨了C#中的数据结构,重点介绍了有序数组和二分查找算法。详细阐述了二分查找的原理,比较了二分查找与顺序查找的效率。接着解释了有序数组的概念,并讨论了在有序数组中添加和删除元素的方法,以及一些其他与有序性相关的操作。最后,提供了有序数组的完整实现代码,包括针对整型和自定义学生类的排序示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.二分查找和顺序查找




二分查找:

    class TestSearch
    {
        public static int BinarySearch(int[] arr, int target)
        {
            int l = 0;
            int r = arr.Length - 1;

            while (l <= r)
            {
                //int mid = (l + r) / 2;  //l和r都是大整型时,可能会溢出
                int mid = l + (r - l) / 2;

                if (target < arr[mid])
                {
                    r = mid - 1;
                }
                else if (target > arr[mid])
                {
                    l = mid + 1;
                }
                else
                {
                    return mid;
                }
            }
            return -1;
        }
    }

2.查找算法性能比较

    class Program
    {
        static void Main(string[] args)
        {
            string filename3 = "测试文件2/游戏会员表.txt";
            string filename4 = "测试文件2/游戏用户表.txt";

            int[] arr3 = TestSearch.ReadFile(filename3);
            int[] arr4 = TestSearch.ReadFile(filename4);
            Console.WriteLine("游戏会员数量:" + arr3.Length);
            Console.WriteLine("调查用户数量:" + arr4.Length);

            Console.WriteLine();

            Stopwatch t3 = new Stopwatch();
            Stopwatch t4 = new Stopwatch();

            Console.WriteLine("顺序查找法");
            t3.Start();
            int sum3 = 0;
            for (int i = 0; i < arr4.Length; i++)
            {
                int target = arr4[i];
                if (TestSearch.OrderSearch(arr3, target) == -1)
                    sum3++;
            }
            t3.Stop();
            Console.WriteLine("查找到:" + sum3 + "个普通玩家");
            Console.WriteLine("运行时间:" + t3.ElapsedMilliseconds + "ms");

            Console.WriteLine();

            Console.WriteLine("二分查找法");
            t4.Start();
            Array.Sort(arr3);
            int sum4 = 0;
            for (int i = 0; i < arr4.Length; i++)
            {
                int target = arr4[i];
                if (TestSearch.BinarySearch(arr3, target) == -1)
                {
                    sum4++;
                }
            }
            t4.Stop(); 
            Console.WriteLine("查找到:" + sum4 + "个普通玩家");
            Console.WriteLine("运行时间:" + t4.ElapsedMilliseconds + "ms");


            Console.Read();
        }
    }

3.什么是有序数组


有序数组(Rank方法):

    class SortedArray1<Key> where Key : IComparable<Key>
    {
        private Key[] keys;
        private int N;

        public SortedArray1(int capacity)
        {
            keys = new Key[capacity];
        }

        public SortedArray1() : this(10) { }

        public int Count { get { return N; } }

        public bool ISEmpty { get { return N == 0; } }

        public int Rank(Key key)
        {
            int l = 0;
            int r = N - 1;

            while (l <= r)
            {
                //int mid = (l + r) / 2;  //l和r都是大整型时,可能会溢出
                int mid = l + (r - l) / 2;

                if (key.CompareTo(keys[mid]) < 0)
                    r = mid - 1;        //在keys[l...mid-1]查找key
                else if (key.CompareTo(keys[mid]) > 0)
                    l = mid + 1;        //在keys[mid+1...r]查找key
                else
                    return mid;         //找到key,并返回索引
            }
            return l;
        }
    }

4.添加、删除元素

添加:

        public void Add(Key key)
        {
            int i = Rank(key);

            if (i < N && keys[i].CompareTo(key) == 0)
                return;

            for (int j = N-1; j >= i; j--)
                keys[j + 1] = keys[j];

            keys[i] = key;
            N++;
        }

删除:

        public void Remove(Key key)
        {
            if (IsEmpty)
                return;

            int i = Rank(key);

            if (i == N || keys[i].CompareTo(key) != 0)
                return;

            for (int j = i+1; j <= N-1; j++)
                keys[j - 1] = keys[j];

            N--;
            keys[N] = default(Key);
        }

5.其他有序性相关方法

有序数组完整代码:

    class SortedArray1<Key> where Key : IComparable<Key>
    {
        private Key[] keys;
        private int N;

        public SortedArray1(int capacity)
        {
            keys = new Key[capacity];
        }

        public SortedArray1() : this(10) { }

        public int Count { get { return N; } }

        public bool IsEmpty { get { return N == 0; } }

        public int Rank(Key key)
        {
            int l = 0;
            int r = N - 1;

            while (l <= r)
            {
                //int mid = (l + r) / 2;  //l和r都是大整型时,可能会溢出
                int mid = l + (r - l) / 2;

                if (key.CompareTo(keys[mid]) < 0)
                    r = mid - 1;        //在keys[l...mid-1]查找key
                else if (key.CompareTo(keys[mid]) > 0)
                    l = mid + 1;        //在keys[mid+1...r]查找key
                else
                    return mid;         //找到key,并返回索引
            }
            return l;
        }

        public void Add(Key key)
        {
            int i = Rank(key);

            if (N == keys.Length)       //扩容
                ResetCapacity(2 * keys.Length);

            if (i < N && keys[i].CompareTo(key) == 0)
                return;

            for (int j = N - 1; j >= i; j--)
                keys[j + 1] = keys[j];

            keys[i] = key;
            N++;
        }

        public void Remove(Key key)
        {
            if (IsEmpty)
                return;

            int i = Rank(key);

            if (i == N || keys[i].CompareTo(key) != 0)
                return;

            for (int j = i + 1; j <= N - 1; j++)
                keys[j - 1] = keys[j];

            N--;
            keys[N] = default(Key);

            if (N == keys.Length / 4)       //缩容
                ResetCapacity(keys.Length / 2);
        }

        public Key Min()
        {
            if (IsEmpty)
                throw new ArgumentException("数组为空!");

            return keys[0];
        }

        public Key Max()
        {
            if (IsEmpty)
                throw new ArgumentException("数组为空!");

            return keys[N - 1];
        }

        public Key Select(int k)
        {
            if (k < 0 || k >= N)
                throw new ArgumentException("索引越界!");

            return keys[k];
        }

        public bool Contains(Key key)
        {
            int i = Rank(key);

            if (i < N && keys[i].CompareTo(key) == 0)
                return true;
            return false;
        }

        //找出小于或等于key的最大键
        public Key Floor(Key key)
        {
            int i = Rank(key);

            if (i < N && keys[i].CompareTo(key) == 0)
                return keys[i];

            if (i == 0)
                throw new ArgumentException("没有找到小于或等于" + key + "的最大键");
            else
                return keys[i - 1];
        }

        //找出大于或等于key的最小键
        public Key Ceiling(Key key)
        {
            int i = Rank(key);

            if (i == N)
                throw new ArgumentException("没有找到大于或等于" + key + "的最小键");
            else
                return keys[i];
        }

        //调整数组容量大小
        private void ResetCapacity(int newCapacity)
        {
            Key[] newKeys = new Key[newCapacity];
            for (int i = 0; i < N; i++)
            {
                newKeys[i] = keys[i];
            }
            keys = newKeys;
        }

        //输出链表类信息
        public override string ToString()
        {
            StringBuilder res = new StringBuilder();
            res.Append("[");
            for (int i = 0; i < N; i++)
            {
                res.Append(keys[i]);
                if (i != N - 1)
                    res.Append(", ");
            }
            res.Append("]");
            return res.ToString();
        }
    }

测试整型:

    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = { 84, 48, 68, 10, 18, 98, 12, 23, 54, 57, 33, 16, 77, 11, 29 };

            SortedArray1<int> sortedArray1 = new SortedArray1<int>();
            for (int i = 0; i < arr.Length; i++)
                sortedArray1.Add(arr[i]);

            Console.WriteLine(sortedArray1);
            Console.WriteLine(sortedArray1.Min());
            Console.WriteLine(sortedArray1.Max());
            Console.WriteLine(sortedArray1.Select(5));
            Console.WriteLine(sortedArray1.Floor(15));
            Console.WriteLine(sortedArray1.Ceiling(15));
            sortedArray1.Remove(23);
            Console.WriteLine(sortedArray1);

            Console.Read();
        }
    }


创建学生类:

    class Student:IComparable<Student>
    {
	    //Student是一个可比较的类型
	    //实现了IComparable<Student>接口中的比较方法CompareTo()
        private string name;
        private int tall;

        public Student(string name,int tall)
        {
            this.name = name;
            this.tall = tall;
        }

        //自定义比较大小的方法
        //通过身高进行比较
        public int CompareTo(Student other)
        {
            if (this.tall > other.tall) return 1;
            if (this.tall < other.tall) return -1;
            return 0;
        }

        public override string ToString()
        {
            return "{" + name + ":" + tall + "}";
        }
    }

测试学生类排序:

    class Program
    {
        static void Main(string[] args)
        {
            Student[] students =
            {
                new Student("小明",180),
                new Student("小红",150),
                new Student("小芳",175),
                new Student("小华",160),
                new Student("小李",190),
            };
            SortedArray1<Student> s = new SortedArray1<Student>();

            for (int i = 0; i < students.Length; i++)
                s.Add(students[i]);

            Console.WriteLine(s);

            Console.Read();
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值