链接:C# 数据结构_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1a541147Nk/?spm_id_from=333.337.search-card.all.click&vd_source=6eb7d966aa03ff5cb02b63725f651e68
链接:使用 C#.Net 学习掌握数据结构 (更新中)_哔哩哔哩_bilibili
一个:
C#编程-第五季-数据结构和算法-宇宙最简单教程_哔哩哔哩_bilibili
C#编程-第六季-编程内功修炼-算法-宇宙最简单教程_哔哩哔哩_bilibili
一、数据结构
基础语法、 数据结构与算法、网络编程与多线程、网络通信、队列、WPF基础、Winform基础、数据库基础、容器、docker、prism框架。 WebApi。
RemoveAt:根据索引移除
1、列表
1.1、线性表
顺序表的存储:顺序表中的每个元素占w个存储单元,设第i个数据元素的存储地址为Local(ai)则有:Local(ai)=Local(a1)+(i-1)*w。也是顺序表的起始地址,顺序表的基地址,顺序表任意存取的特点,占用的是一组连续的存储空间,具有任意存取的特点,数组具有天生表示顺序表的数据存储区域的特性。
在这个例子中,索引器允许你通过索引来读取(get
)和写入(set
)SeqList<T>
中的元素。如果SeqList<T>
没有索引器,并且你试图像数组一样使用它(即mySeqList[index]
),编译器会报错,因为它不知道如何处理这样的语法。
因此,如果你在使用自定义集合类(如SeqList<T>
)时遇到索引相关的错误,很可能是因为该类没有实现索引器,或者你尝试访问的索引超出了集合的有效范围。确保你的类正确实现了索引器,并在使用索引器时始终检查索引的有效性,以避免IndexOutOfRangeException
异常。
代码:
interface IList1<T>
{
int GetLength();
void Clear();
bool IsEmpty();
void Add(T item);
void Insert(T item, int index);
T Delete(int index);
//T this[int index] { get; }
T GetEle(int index);
int Locate(T value);
}
internal class SeqList<T> : IList1<T>
{
/// 顺序表实现方式
public T[] data; // 存储数据
public int count = 0; // 表示存了多少个数据
public SeqList(int size) // size最大容量
{
data = new T[size];
}
public SeqList() : this(10) // 默认构造函数容量是10
{
}
public T this[int index]
{
get { return GetEle(index); }
}
public void Add(T item)
{
if (count == data.Length)
{
Console.WriteLine("当前数组已存满,不允许再存");
}
else
{
data[count] = item;
count++;
}
}
public void Clear()
{
throw new NotImplementedException();
}
public T Delete(int index)
{
T item = data[index];
for(int i = index - 1; i < count - 1; i++)
{
data[i] = data[i + 1];
}
count--;
return item;
}
public T GetEle(int index)
{
if (index >= 0 && index <= count - 1)
{
return data[index];
}
else
{
Console.WriteLine("索引不存在");
return default(T);
}
}
// 取得数据的长度
public int GetLength()
{
return data.Length;
}
public void Insert(T item, int index)
{
for(int i=count-1; i>=index; i--)
{
data[i] = data[i-1];
}
}
public bool IsEmpty()
{
throw new NotImplementedException();
}
public int Locate(T value)
{
for (int i = 0; i < count-1; i++)
{
if (data[i].Equals(value))
{
return i;
}
}
return -1; /// 表示值不存在;
}
}
2、链表
单链表和双链表:
2.1、单链表
单链表使用地址连续的存储单元顺序存储线性表中的各个数据元素,链式存储,链表不要求逻辑上相邻的数据元素在物理存储位置上页相邻,因此,在对链表进行插入和删除时不需要移动数据元素,但是同时页失去了顺序表可随机存储的有带你。
表头 数据 下一个数据的地址
internal class Node1<T>
{
private T data; // 存储元素
private Node1<T> next; // 用来指向下一个元素
public Node1(T value)
{
data = value;
next = null;
}
public Node1(T value, Node1<T> next)
{
this.data = value;
this.next = next;
}
public Node1()
{
data=default(T);
next= null;
}
public Node1(Node1<T> next)
{
this.next = next;
}
public T Data
{
get { return data; }
set { data = value; }
}
public Node1<T> Next
{
get { return next; }
set { next = value; }
}
}
代码:
interface IList1<T>
{
int GetLength();
void Clear();
bool IsEmpty();
void Add(T item);
void Insert(T item, int index);
T Delete(int index);
//T this[int index] { get; }
T GetEle(int index);
int Locate(T value);
}
internal class linkList<T> : IList1<T>
{
public Node1<T> head; // 第一个节点
public linkList()
{
head = null;
}
public void Add(T item)
{
Node1<T> newNode = new Node1<T>(item); // 根据新的数据创建新的节点
if (head == null)
{
head = newNode;
}
else
{
Node1<T> temp = head;
while (true)
{
if (temp.Next != null)
{
temp = temp.Next;
}
else
{
break;
}
}
temp.Next = newNode;
}
}
public void Clear()
{
throw new NotImplementedException();
}
public T Delete(int index)
{
T data;
if (index == 0)
{
data = head.Data;
head = head.Next;
return data;
}
else
{
Node1<T> temp = head;
for (int i = 0; i < index; i++)
{
temp = temp.Next;
}
data = temp.Next.Data;
temp.Next = temp.Next.Next;
return data;
}
}
public T GetEle(int index)
{
throw new NotImplementedException();
}
public int GetLength()
{
if(head==null) return 0;
Node1<T> temp = head;
int count = 1;
while(temp != null)
{
if(temp.Next != null)
{
count++;
temp= temp.Next;
}
else
{
break;
}
}
return count;
}
public void Insert(T item, int index)
{
Node1<T> newNode=new Node1<T>(item);
if(index==0)
{
newNode.Next = head;
head= newNode;
}
else
{
Node1<T> temp=head;
for (int i=0; i<index; i++)
{
temp = temp.Next;
}
newNode.Next = temp.Next;
temp.Next = newNode;
}
}
public bool IsEmpty()
{
throw new NotImplementedException();
}
public int Locate(T value)
{
Node1<T> temp = head;
if (temp == null)
{
return -1;
}
else
{
int index = 0;
while (true)
{
if (temp.Data.Equals(value))
{
return index;
}
else
{
if(temp.Next!= null)
{
index++;
temp = temp.Next;
}
else
{
break;
}
}
}
return -1;
}
}
}
2.2、双链表
指向前一个节点,先进后除,,没有计数,
3、栈
3.1、顺序栈(Stack)
是操作元素限定在表的尾端进行的线性表,表尾由于要进行插入、删除等操作,所以,它具有特殊的含义,把表尾称为栈顶(Top)另一端固定,叫做栈底,当为空,脚空栈。
栈通常记为:S=(a1, a2, ...,an) a1为栈底元素,an为栈顶元素。a1到an依次入栈,出栈则次序相反,an第一个出栈,a1最后出栈。栈的操作是按照后进先出或现金后出的原则进行
SeqList<string> strList = new SeqList<string>();
strList.Add("123");
strList.Add("456");
strList.Add("789");
Console.WriteLine("123456789");
Console.WriteLine(strList[0]);
Console.ReadLine();
Console.WriteLine(strList);
Console.WriteLine(strList.GetLength());
for (int i = 0; i < strList.GetLength(); i++)
{
Console.WriteLine(strList[i]);
}
Console.ReadLine();
Stack<string> stack = new Stack<string>();
stack.Push("a");
stack.Push("b");
stack.Push("c");
Console.WriteLine(stack.Pop());
Console.ReadLine();
代码: 类似于数组,用数组构造栈的先进后出
interface IsStackDS<T>
{
int Count { get; }
int GetLength();
bool IsEmpty();
void Clear();
void Push(T item);
T Pop();
T Peek();
}
internal class seqStack<T> : IsStackDS<T>
{
private T[] data;
private int top;
public seqStack(int size)
{
data = new T[size];
top = -1;
}
public int Count { get { return top+1; } }
public void Clear()
{
top=-1;
}
public int GetLength()
{
return Count;
}
public bool IsEmpty()
{
return Count==0;
}
public T Peek()
{
throw new NotImplementedException();
}
public T Pop()
{
T temp = data[top];
top--;
return temp;
}
public void Push(T item)
{
data[top+1]=item;
top++;
}
}
3.2、链栈
栈顶Top 为Node1 类 出栈时候指向下一个Node1
其他和单链表类似:
代码: 但是用链表的形式描述栈的先进后出,需要用到类节点 Node
internal class linkStack<T> : IsStackDS<T>
{
private T data;
private Node1<T> top;
private int count;
//public seqStack(int size)
//{
// data = ;
// top = null;
//}
public int Count { get { return count; } }
public void Clear()
{
top = null;
count = 0;
}
public int GetLength()
{
return Count;
}
public bool IsEmpty()
{
return Count == 0;
}
public T Peek()
{
throw new NotImplementedException();
}
public T Pop()
{
data = top.Data;
top=top.Next;
count--;
return data;
}
public void Push(T item)
{
Node1<T> newNode = new Node1<T>(item);
newNode = new Node1<T>(item);
top.Next = top;
top = newNode;
count++;
}
4、队列
代码:队头 队尾 ,先进先出,front 先出,有计数:count。
4.1、顺序队列
用以连片的存储空间老存储队列中的数据元素,这样的队列称为顺序队列(Sequence Queue)。类似于顺序栈,
代码:需要设置数组的大小
interface IsQueueDS<T>
{
int Count { get; }
int GetLength();
bool IsEmpty();
void Clear();
void Enqueue(T item);
T Dequeue();
T Peek();
}
internal class seqQueue<T> : IsQueueDS<T>
{
private T[] data;
private int count;
private int front; // 队首,从 -1 开始
private int rear; // 队尾
public seqQueue(int size)
{
data=new T[size];
count = 0;
front = -1;
rear = -1;
}
public int Count { get { return count; } }
public void Clear()
{
count=0;
}
public T Dequeue()
{
if (count >0)
{
T temp = data[front + 1];
front++;
count--;
return temp;
}
else
{
Console.WriteLine("无法取得,队列为空");
return default(T);
}
}
public void Enqueue(T item)
{
if (count == data.Length)
{
Console.WriteLine("队列已经满了");
}
else
{
if(rear==data.Length-1) // 判断是否在末尾,从头开始
{
data[0]=item;
rear = 0;
}
else
{
data[rear + 1] = item;
rear++;
}
}
}
public int GetLength()
{
return count;
}
public bool IsEmpty()
{
return count == 0 ;
}
public T Peek()
{
T temp=data[front+1];
return temp;
}
}
4.2、链队列
表与链, 栈与队列,不需要设置数组的大小
internal class Node1<T>
{
private T data; // 存储元素
private Node1<T> next; // 用来指向下一个元素
public Node1(T value)
{
data = value;
next = null;
}
public Node1(T value, Node1<T> next)
{
this.data = value;
this.next = next;
}
public Node1()
{
data=default(T);
next= null;
}
public Node1(Node1<T> next)
{
this.next = next;
}
public T Data
{
get { return data; }
set { data = value; }
}
public Node1<T> Next
{
get { return next; }
set { next = value; }
}
}
代码:
interface IsQueueDS<T>
{
int Count { get; }
int GetLength();
bool IsEmpty();
void Clear();
void Enqueue(T item);
T Dequeue();
T Peek();
}
internal class linkQueue<T> : IsQueueDS<T>
{
private Node1<T> front;
private Node1<T> rear;
private T data;
private int count;
public linkQueue()
{
front = null;
rear = null;
count = 0;
}
public int Count { get { return count; } }
public void Clear()
{
front = null;
rear = null ;
count = 0;
}
public T Dequeue()
{
if (count == 0)
{
Console.WriteLine("为空无法出队列");
return default(T);
}
else if(count == 1)
{
T temp = front.Data;
front = null;
rear = null;
count = 0;
return temp;
}
else
{
T temp = front.Data;
temp=front.Data;
front=front.Next;
count--;
return temp;
}
}
public void Enqueue(T item)
{
Node1<T> newNode = new Node1<T>(item);
if (count == 0)
{
front = newNode;
count = 1;
rear= newNode;
}
else
{
rear.Next = newNode;
rear = newNode;
count++;
}
}
public int GetLength()
{
return count;
}
public bool IsEmpty()
{
return count == 0 ;
}
public T Peek()
{
return front.Data;
}
}
5、字符串
字符串类的创建
6、数组
数组的创建:
7、算法
算法:
7.1、快速排序
作为排序依据的数据项称为 ”排序项“,也成为记录的 ”关键码“,关键码分为主关键码和次关键码。一般地,若关键码是主关键码,则对于任意排序的序列,经排序后得到的结果是唯一的;弱为次关键码,排序结果不唯一,这是因为待排序的序列中可能存在具有相同关键码的记录。此时,这些记录在排序结果中,他们之间的位置关系与排序前不一定保持一致。如果使用某个排序方法对任意的记录序列关键码进行排序,形同关键码值得记录之间得位置关系与排序前一致,则称此排序方法是稳定的,如果不一致,则称此排序方法是不稳定的。
由于待排序得记录得数量不同,使得排序过程中设计得存储器不同,可将排序方法分为内部排序和外部排序两大类。
内部排序值得是在排序过程中,记录全部存放在计算机得内存中,并在内存中调整记录之间得相对位置,在此期间没有进行内、外存的数据交换。外部排序指的是在排序过程中,记录得主要部分存放在外存中,借助于内存逐步调整记录之间得相对位置。在这个过程中,需要不断地在内外存之间交换数据。
排序:排序项,
快速排序:
7.1.1、直接插入排序
双重循环,逐个比较排序,直接拿后一个与前边所有去比较
7.1.2、冒泡排序
将相邻得记录得关键码进行比较,若前边记录的关键码大于后边记录的关键码,则将它们交换,否则不交换。需要操作N-1次,,N为元素个数。
7.1.3、简单选择排序
先将第一个作为比较直,与后边得所有元素中得最小值比较,然后交换位置。
7.1.4、快速排序
先取得一个基数,即0位置,,然后从后索引找到比它小的,再从前往后找比它小的。
直到基数放在某个位置使得将数组分为两个部分。前边都比基数小,后边都比基数大。
internal class Program
{
static void QuickSort(int[] dataArray,int left,int right)
{
if(left<right)
{
int x = dataArray[left];
int i = left;
int j = right;
while(true&&i<j)
{
while (true && i < j)
{
if (dataArray[j] <= x)
{
dataArray[i] = dataArray[j];
break;
}
else
{
j--;
}
}
while (true && i < j)
{
if ((dataArray[i] >x))
{
dataArray[j] = dataArray[i];
break;
}
else
{
i++;
}
}
}
// 此时i==j找到中间位置
dataArray[i] = x;
QuickSort(dataArray,left,i-1);
QuickSort(dataArray,i+1,right);
}
}
static void Main(string[] args)
{
int[] data = new int[] { 42, 20, 17, 27, 13, 8, 17, 48 };
QuickSort(data,0,data.Length-1);
foreach(var temp in data)
{
Console.WriteLine(temp);
}
}
7.1、二叉树
算法、重点