using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataList.Scrips.ArrayList
{
/// <summary>
/// 数组:线性数据结构,连续的存储空间存储相同数据类型的数据结构
/// 随机访问性:因为数组是连续的内存空间,所以数组具有随机访问性,随机访问的时间复杂度为O(1)
/// 数组的插入,删除操作:相比链表,数据的插入删除操作的时间复杂度在最好的情况下为O(1)【对数组的最后面元素进行操作】,在最坏的情况下O(n)【0~n之间的元素进行操作】
/// 平均时间复杂度为O(n)【计算方式(1+2+3+...+n)/(n)】
/// 原因:数组需要连续的存储空间,所以每次进行插入删除操作时,为了保证数组空间的连续行,都需要进行数据的搬迁
/// 为了提高插入操作的效率,在数组中数组没有规律的情况下,不要求规则的情况下,可以把指定插入的数据元素放在数组的末尾,把要插入的数据元素直接插入到指定的位置
/// 时间复杂度为O(1)
/// 删除操作:在做删除操作的时候,可以先把要删除的位置标记下来,但是并不做删除,不做数据元素的搬迁,待数组中没有足够的空间时,再做删除操作,搬迁数组数据元素
/// 数组的越界问题:数组越界是因为访问了数组受限的内存
/// 数组的动态扩容:在向数组中添加数据元素的时候,数组的内存空间不够,需要扩大数组的内容,然后再将数组中的元素复制到新的数组中
/// 数组下标访问:首地址+数据类型大小*k
/// </summary>
class ArrayTest
{
int[] array;
int last;
int Maxcount;
public ArrayTest(int size)
{
array = new int[size];
Maxcount = size;
last = -1;
}
public void Append(int item)
{
if (last < Maxcount - 1)
array[++last] = item;
}
public void Insert(int i, int item)
{
if (i < 1 || last == Maxcount - 1 || i > last + 2)
return;
if (i == last + 2)
array[last + 1] = item;
else
{
int j = 0;
for (; j < i - 1; ++j)
{
array[j + 1] = array[j];
}
array[i - 1] = item;
}
++last;
}
public int Delet(int i)
{
int temp = array[0];
if (last == -1)
return -1;
if (i < 1 || i > last + 1)
return -1;
if (i == last + 1)
{
temp = array[last--];
}
else
{
temp = array[i - 1];
int j = i;
for (; j <= last; ++j)
{
array[j] = array[j + 1];
}
}
--last;
return temp;
}
public int GetIndex(int item)
{
int pos = -1;
for (int i = 0; i < Maxcount; ++i)
{
if (array[i] == item)
{
pos = i;
break;
}
}
return pos;
}
public int GetlocalValue(int i)
{
if (i < 1 || i > last + 2)
return -1;
return array[i - 1];
}
public void Print()
{
for (int i = 0; i < Maxcount; ++i)
{
Console.WriteLine(array[i]);
}
}
}
/// <summary>
/// 链表:链表是一种不需要连续内存的线性表数据结构 链表是通过指针将一串不连续的内存片段串联起来 内存块称为节点(node[data、next]) next指向下一个节点的地址(后继指针)
/// 单链表:单链表中的节点只有后继节点没有前驱节点,末尾节点的后继节点为null节点,头节点就是单链表的基地址,有了它就可以遍历到链表中的全部节点
/// 单链表的操作:插入、删除、查找
/// 插入操作:由于单链表的内存不是连续的,所以单链表的插入操作不需要数据的搬迁操作,所以单链表的插入操作的时间复杂度为O(1)
/// 查找操作:由于单链表的内存不是连续的,所以单链表不查找操作不能像数组那个根据首地址+n个数据类型占用字节数计算,需要遍历链表直到找到,时间复杂度O(n)
/// 删除操作:删除操作不需要数据的搬迁,所以时间复杂度O(1)
///
/// 循环链表:循环链表是,单链表的末尾节点指向头节点
/// 双向链表:单链表的节点中有俩个域,一个指向前驱节点的地址,一个指向后继节点的地址
/// 双向循环链表:双向链表的末尾指针指向双向链表的头节点
/// 双向链表的插入操作和删除操作的都比单链表简单,因为不需要查找节点的前驱节点
///
/// 单链表和数组的区别:1.数组需要连续的存储内存,单链表不需要
/// 2.单链表的删除,插入操作比数组的方便,不需要数据的搬迁
/// 3.单链表的查找操作,需要遍历链表直到找到对应的节点
/// 4.单链表对内存的要求比较低,会比较浪费内存,是一种以空间换取时间的优化方式
///
/// 熟练掌握单链表的操作:1.插入:
/// 2.删除:
/// 3.查询:
/// 4.单链表翻转:
/// 5.单链表中环的检测
/// 6.俩个有序单链表的合并
/// 7.求链表中间节点
///
/// 栈:栈是一种受限的数据结构,只能在栈顶进行操作(栈顶插入、删除元素),先进后出,后进先出的数据结构,
/// 栈的存储方式:1.顺序存储
/// 2.链式存储
/// 栈的基本操作:1.入栈(栈顶插入元素)
/// 2.出栈(栈顶删除元素)
/// 栈的应用:1.栈在函数中的应用,局部变量存储在栈中
/// 2.栈在表达式中的应用,表达式求值
/// 3.栈在括号匹配中的应用
///
/// 队列:队列也是一种操作受限的数据结构,在队尾插入元素(入队),对头删除元素(出队),先进先出,后进后出的数据结构
/// 队列的存储方式:1.顺序队列
/// 2.链式队列
/// 3.循环队列
/// 4.阻塞队列和并发队列
/// 队列的基本操作:1.入队
/// 2.出队
/// 队列的应用:
///
///
/// </summary>
///
class ListNode
{
public int data;
public ListNode next;
public ListNode(int data)
{
this.data = data;
}
public ListNode()
{
}
int[] a = new int[2] { 1, 2 };
int[] b = new int[4];
void test()
{
a.CopyTo(b, 2);
}
}
class LinkListTest
{
public void Insert(int i, int value, ListNode head)
{
ListNode desNode = new ListNode(value);
if (head == null)
{
desNode = head;
return;
}
if (i == 1)
{
desNode.next = head;
head = desNode;
}
if (head != null)
{
ListNode p = new ListNode();
ListNode r = new ListNode();
p = head;
int j = 1;
while (p != null && j < i)
{
r = p;
p = p.next;
++j;
}
if (i == j)
{
r.next = desNode;
desNode.next = p;
}
}
}
public int DeleteItem(int i, ListNode head)
{
if (head == null) return -1;
int temp = -1;
ListNode p = new ListNode();
p = head;
int j = 1;
while (p.next != null)
{
p = p.next;
++j;
}
if (i == j)
{
temp = p.data;
p = p.next.next;
}
List<int> a = new List<int> { 1, 2, 3, 4, 5, 6 };
a.ToArray();
return temp;
}
public void InsertPos(int i, int value, ListNode head)
{
ListNode desNode = new ListNode(value);
if (head == null)
{
head = desNode;
head.next = null;
}
if (i == 1)
{
desNode.next = head.next;
head.next = desNode;
}
if (head != null)
{
ListNode p = new ListNode();
p = head;
int j = 1;
while (p.next != null && j < i)
{
p = p.next;
++j;
}
if (i == j)
{
desNode.next = p.next.next;
p.next = desNode;
}
}
}
}
class StackList
{
public int n;//栈的大小
public int count;//栈中元素的个数
public int[] a;
public StackList(int _n)
{
a = new int[_n];
n = _n;
this.count = 0;
}
public bool Push(int value)
{
if (n == count) return false;
a[count] = value;
++count;
return true;
}
public int Pop()
{
if (count == 0) return -1;
int temp = a[count - 1];
count--;
return temp;
}
}
class LinkStackNode
{
public int data;
public LinkStackNode next;
public LinkStackNode()
{
}
public LinkStackNode(int data)
{
this.data = data;
}
}
class LinkStack
{
LinkStackNode tail;
public LinkStack(LinkStackNode _tail)
{
tail = _tail;
}
public void Push(int value)
{
LinkStackNode q = new LinkStackNode(value);
if (tail == null)
{
tail = q;
}
else
{
tail.next = q;
q = tail;
}
}
public int Delete()
{
if (tail == null) return -1;
LinkStackNode p = new LinkStackNode();
p = tail;
tail = tail.next;
return p.data;
}
}
class QueueList
{
public int[] a;
public int n=0;
public int head=0;
public int tail=0;
public QueueList()
{
}
public QueueList(int n)
{
a = new int[n];
this.n = n;
head = 0;
tail = 0;
}
public bool EnQueue(int value)
{
if (tail == n) return false;
a[tail] = value;
++tail;
return true;
}
public int DeQueue()
{
if (head == tail) return -1;
int temp = a[head];
++head;
return temp;
}
}
class QueueLinkNode
{
public int data;
public QueueLinkNode next;
public QueueLinkNode() { }
public QueueLinkNode(int data)
{
this.data = data;
next = null;
}
}
class QueueLink
{
public QueueLinkNode head;
public QueueLinkNode tail;
public QueueLink(QueueLinkNode head,QueueLinkNode tail)
{
this.head = head;
this.tail = tail;
}
public bool EnQueue(int value)
{
QueueLinkNode q = new QueueLinkNode(value);
if (tail == null)
tail = q;
else
{
tail.next = q;
tail = q;
}
return true;
}
public int DeQueue()
{
if (head == tail) return -1;
QueueLinkNode p = new QueueLinkNode();
p = head;
QueueLinkNode q = new QueueLinkNode();
while (p.next != null)
{
q = p;
p = p.next;
}
return q.data;
}
}
}
链表,栈,队列总结
最新推荐文章于 2022-10-23 23:26:35 发布