1 第十六天
非数值数据之间的结构关系,以及如何表示,如何存储,如何处理
1.1 自定义ArrayList
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 数据结构 {
class MyArrayList {
private int m_Allsize = 0;//总容纳量
private int m_used = 0;//实际占有量
private object[] m_pdata;//用来存储里面的数据元素
private const int Maxsize = 5;//扩容参数
public int Count {
get { return m_used; }
}
public int Capacity {
get { return m_Allsize; }
}
//构造
public MyArrayList() {
Realloc(Maxsize);
}
//给动态数组添加元素
public void Add(object enemelt) {
if (m_used < m_Allsize) {
m_pdata[m_used] = enemelt;//新加元素
} else {
int newSize = m_used + Maxsize;//开辟的新的容纳量大小;
Realloc(newSize);
m_pdata[m_used] = enemelt;//新加元素
}
m_used++;
}
//开辟新空间增加容纳量的方法
public void Realloc(int newSize) {
object[] pdata = m_pdata;//旧数组元素转存
m_pdata = new object[newSize];//开辟新数组
//当新开辟的空间比实际空间还小的时候,以新开辟的为准,能存多少存多少,防止数据溢出
int copySize = m_used > newSize ? newSize : m_used;
for (int i = 0; i < copySize; i++) {//旧数组元素放到新数组中
m_pdata[i] = pdata[i];
}
if (m_used > newSize) {
m_used = newSize;
}
m_Allsize = m_pdata.Length;//总容纳量
}
//插入
public void Insert(object enemelt, uint position) {
if (position>m_used) {//超出界限
throw new Exception("插入错误");//人为抛出异常
}
if (m_used+1>m_Allsize) {//正好满了
int newSize = m_used + Maxsize;//开辟的新的容纳量大小;
Realloc(newSize);
}
for (int i = m_used; i >=position; i--) {//通过for循环将position位置之后的元素往后挪一个,将position空出来
m_pdata[i] = m_pdata[i - 1];
}
m_pdata[position] = enemelt;//将空出的position位置给添加上新的元素
m_used++;
}
//索引器
public object this[int index] {
get {
if (index > m_used) {
throw new Exception("超出界限");
} else {
return m_pdata[index];
}
}
set {
if (index > m_used) {
throw new Exception("超出界限");
} else {
m_pdata[index] = value;
}
}
}
//AddRange的方法;
public void AddRange<T>(T[] enemelt) {
if (m_used + enemelt.Length < m_Allsize) {
for (int i = 0; i < enemelt.Length; i++) {
m_pdata[m_used] = enemelt[i];//新加元素
m_used++;
}
} else {
int newSize = 0;
if (m_used < m_Allsize) {
newSize = m_used + enemelt.Length;//开辟的新的容纳量大小;
} else {
newSize = m_used + enemelt.Length + Maxsize;//开辟的新的容纳量大小;
}
Realloc(newSize);
for (int i = 0; i < enemelt.Length; i++) {
m_pdata[m_used] = enemelt[i];//新加元素
m_used++;
}
}
}
//下标删除
public void RemoveAt(int position) {
if (position>=m_used) {
throw new Exception("越界");
}
for (int i = position; i < m_used-1; i++) {
m_pdata[i] = m_pdata[i+1];
}
m_used--;
if (m_used < Maxsize) {//特殊情况下扩容,可不写
Realloc(Maxsize);
}
}
//元素删除
public void Remove(object enemelt) {
int index = Array.IndexOf(m_pdata,enemelt);//获取元素的下标
if (index >= 0) {//递归跳出的条件
RemoveAt(index);
Remove(enemelt);//递归调用本身,删除多个相同元素
} else {
if (m_used < Maxsize) {//特殊情况下扩容,可不写
Realloc(Maxsize);
}
}
}
//清除
public void Clear() {
for (int i = 0; i < m_used; i++) {
m_pdata[i] = null;
}
m_used = 0;
m_Allsize = 0;
Realloc(Maxsize);
}
}
}
1.2 自定义链表(线性表)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 数据结构 {
//节点类
public class Node<T> {
//直接前驱,单向链表不需要
//直接后继
private Node<T> m_next;//以类的类型为节点类型,这个整个类中都可以使用
//存储链表里的元素
private T m_pdata;//节点
public Node<T> Next{
get { return m_next; }
set { m_next = value; }
}
public T Data {
get { return m_pdata; }
set { m_pdata = value; }
}
public Node() {
m_next = null;
m_pdata = default(T);//给泛型赋初值的方式,没有意义,相当于int a= 0;
}
public Node(T pdata) {
m_next = null;
m_pdata = pdata;
}
}
public class MyList<T> {
private uint m_size;//链表的长度
private Node<T> m_head;//链表头节点
private Node<T> m_end;//尾节点
//长度属性
public uint Count {
get { return m_size; }
}
public bool Isempty {
get { return m_head == null; }
}
//添加元素
public void Push(T pdata) {
Node<T> newNode = new Node<T>(pdata);
if (Isempty) {//链表为空时,第一个节点即是头节点也是尾节点
m_head = newNode;
} else {//非空时,新节点会变成原来尾节点的后继节点,新的尾节点。
m_end.Next = newNode;
}
m_end = newNode;
++m_size;
}
//前插入
public bool FInsert(T pdata,uint position) {
//没成功
if (Isempty) {//链表为空
Console.WriteLine("链表为空,不可以插入");
return false;
} else if (position > m_size) {
Console.WriteLine("超界");
return false;
}
//插入成功
if (position == 0) {
Node<T> newNode = new Node<T>(pdata);
newNode.Next = m_head;//新节点的指向头节点
m_head = newNode;//新节点变成头节点
++m_size;
return true;
} else {
Node<T> tempNode = m_head;//存储头节点
Node<T> tempFront = null;//临时前驱
uint tempindex = 1;//临时位置,之所以从1开始,是因为0的情况上面已经判断过了
while (tempNode.Next!= null&&tempindex<=position) {//找插入的位置
tempFront = tempNode;
tempNode = tempNode.Next;
++tempindex;
}
Node<T> newNode = new Node<T>(pdata);
tempFront.Next = newNode;//将前驱节点的后继节点改成新节点
newNode.Next = tempNode;//将新节点的后继节点改成原插入的节点
++m_size;
return true;
}
}
//后插入
public bool BInsert(T pdata,int position) {
//没成功
if (Isempty) {//链表为空
Console.WriteLine("链表为空,不可以插入");
return false;
} else if (position > m_size) {
Console.WriteLine("超界");
return false;
}
//插入成功
Node<T> newNode = new Node<T>(pdata);
if (position == 0) {//往头后面插
newNode.Next = m_head.Next;//新节点后继变成头节点的后继
m_head.Next = newNode;//头节点的后继变成新节点
} else if (position == m_size-1) {//往尾巴后面插
m_end.Next = newNode;
m_end = newNode;
} else {
Node<T> tempNode = m_head;//存储头节点
uint tempindex = 1;//临时位置,之所以从1开始,是因为0的情况上面已经判断过了
while (tempNode.Next != null && tempindex <= position) {//找插入的位置,后插入,不需要前节点
tempNode = tempNode.Next;
++tempindex;
}
newNode.Next = tempNode.Next;//新节点的后继变成原节点的后继
tempNode.Next = newNode;//将原的后继节点改成新节点
}
++m_size;
return true;
}
//删除
public bool Remove(int position) {
//没成功
if (Isempty) {//链表为空
Console.WriteLine("链表为空,不可以删除");
return false;
} else if (position > m_size) {
Console.WriteLine("超界");
return false;
}
if (position == 0) {
m_head = m_head.Next;
} else {
Node<T> tempNode = m_head;//存储头节点
Node<T> tempFront = null;//临时前驱
uint tempindex = 1;//临时位置,之所以从1开始,是因为0的情况上面已经判断过了
while (tempNode.Next != null&&tempindex <= position) {//找删除的位置
tempFront = tempNode;
tempNode = tempNode.Next;
++tempindex;
}
tempFront.Next = tempNode.Next;
if (position == m_size - 1) {//如果删除的是尾节点,就把前驱节点给尾节点。
m_end = tempFront;
}
}
--m_size;
GC.Collect();//强制垃圾回收
return true;
}
//清除
public void Clear() {
for (int i = 0; i <= m_size-1; i++) {
m_head = m_head.Next;
}
//m_head = null;
m_end = null;
GC.Collect();//强制垃圾回收
}
//索引函数
public T ElenentIndex(uint index) {
T temp = default(T);//临时变量
if (Isempty) {
Console.WriteLine("链表为空");
} else {
Node<T> tempNode = m_head;
uint tempindex = 1;
while (tempNode.Next != null && tempindex <= index) {//找删除的位置
tempNode = tempNode.Next;
++tempindex;
}
temp = tempNode.Data;
}
return temp;
}
}
}
1.3 自定义顺序栈
public class Stack<T> {
private uint m_allsize = 0;//总长度
private T[] pdata;//栈内元素存储
private int m_top = -1;//栈顶指针,本程序中栈顶元素不占用一个空间,而是指向栈顶元素
public bool IsEmpty {//是否为空
get { return m_top < 0; }
}
public bool IsFull {//栈是否已经满了
get { return m_top >= m_allsize - 1; }
}
public Stack() {//默认无参构造
}
public Stack(uint size) {//初始化构造
m_allsize = size;
m_top = -1;
pdata = new T[m_allsize];
}
//入栈操作
public bool Push(T data) {
if (IsFull) {
Console.WriteLine("栈内已满,不能添加");
return false;
}
pdata[++m_top] = data;//之所以前++,是因为m_top从-1开始
return true;
}
//出栈
public T Pop() {
if (IsEmpty) {
Console.WriteLine("栈内为空");
return default(T);//返回泛型默认值,什么都没有
}
return pdata[m_top--];
}
//取栈顶元素,不出栈
public T Peek() {
if (IsEmpty) {
Console.WriteLine("栈内为空");
return default(T);//返回泛型默认值,什么都没有
}
return pdata[m_top];//top指向栈顶元素
}
}
1.4 自定义链表栈
//链式栈
public class StackNode<T> {//节点类
private StackNode<T> m_next;
private T m_data;
public StackNode<T> Next {
get { return m_next; }
set { m_next = value; }
}
public T Data {
get { return m_data; }
set { m_data = value; }
}
public StackNode() {
}
public StackNode(T data) {
m_data = data;
}
}
public class LinkStack<T> {
private uint m_size = 0;//总长度
private StackNode<T> m_top = null;//栈顶对象
public bool IsEmpty {
get { return m_top == null; }
}
public uint Count {
get { return m_size; }
}
//入栈操作
public void Push(T data) {
StackNode<T> newNode = new StackNode<T>(data);
if (IsEmpty) {
m_top = newNode;
} else {
newNode.Next = m_top;
m_top = newNode;
}
++m_size;
}
//出栈
public T Pop() {
if (IsEmpty) {
Console.WriteLine("栈为空");
return default(T);
}
StackNode<T> tempNode = m_top;
m_top = m_top.Next;
--m_size;
return tempNode.Data;
}
//取栈顶元素
public T Peek() {
if (IsEmpty) {
Console.WriteLine("栈为空");
return default(T);
}
return m_top.Data;
}
}
1.5 自定义链表队列
public class QueueNode<T> {//节点类
private T m_data;
private QueueNode<T> m_next;
public QueueNode<T> Next {
get { return m_next; }
set { m_next = value; }
}
public T Data {
get { return m_data; }
set { m_data = value; }
}
public QueueNode(){
}
public QueueNode(T data) {
m_data = data;
}
}
public class LinkQueue<T> {
private QueueNode<T> m_top=null;
private QueueNode<T> m_wei=null;
private int m_size=0;
public int Count {
get { return m_size; }
}
public bool IsEmpty {
get { return m_top == null && m_wei == null; }
}
//入队
public bool Push(T data) {
QueueNode<T> newNode = new QueueNode<T>(data);
if (IsEmpty) {
m_top = newNode;
m_wei = newNode;
} else {
m_wei.Next = newNode;
m_wei = newNode;
}
++m_size;
return true;
}
//出队
public T Pop() {
if (IsEmpty) {
Console.WriteLine("队列为空");
return default(T);
}
QueueNode<T> temp = m_top;
m_top = m_top.Next;
--m_size;
if (m_top == null) {
m_wei = null;
}
return m_top.Data;
}
//清理队列
public void Clear() {
QueueNode<T> temp = m_top;
while (temp!= null) {
m_top = m_top.Next;
temp = null;
temp = m_top;
}
m_wei = null;
m_size = 0;
}
}