标签:通过 tin exp 数组 ddr head 方法 round max
跟上一篇《数据结构,你还记得吗(中)》目录进行一一对应,以此来提升理解。
int[] arr = { 1, 2, 3, 5, 6 };
int length = arr.Length / 2;
for(int i=0;i<length; i++)
{
int temp = arr[i];
arr[i] = arr[arr.Length - i-1];
arr[arr.Length - i-1] = temp;
}
List和ArrayList自带反转函数 Reverse();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int min =int.MaxValue;
int secondMin = int.MaxValue;
int[] arr = { 1, 3, 5, 6, 8, 9, 10, 66 , 66 ,55,88,66,22,55,58};
for (int i = 0; i < arr.Length; i++)
{
int num = arr[i];
if (num < min)
{
secondMin = min;
min = num;
}
else
secondMin = num < secondMin ? num : secondMin;
};
stopwatch.Stop();
Console.WriteLine(secondMin+"花费时间{0}",stopwatch.Elapsed.ToString());
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int[] arr = { 1, 3, 5, 6, 8, 9, 10, 66 , 66 ,55,88,66,22,55,581,1,3,5,6};
Dictionary<int, List<int>> dic = new Dictionary<int, List<int>>();
int index = 0;
for (int i = 0; i < arr.Length; i++)
{
index++;
if (!dic.ContainsKey(arr[i]))
{
dic.Add(arr[i], new List<int> { index });
}
else
{
dic[arr[i]].Add(index);
}
};
int minIndex = int.MaxValue;
int temp=0 ;
foreach(var k in dic.Keys)
{
if(dic[k].Count==1)
{
foreach(var v in dic[k])
{
if (minIndex > v)
{
minIndex = v;
temp = k;
}
}
}
}
stopwatch.Stop();
Console.WriteLine(temp + "花费时间{0}",stopwatch.Elapsed.ToString());
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int[] arr = { 1, 3, 5, 6, 8, 9, 10, 66, 66, 55, 88, 66, 22, 55, 581, 1};
foreach (var a in arr)
{
int firstIndex = Array.IndexOf(arr, a);
int lastIndex = Array.LastIndexOf(arr, a);
if (firstIndex == lastIndex)
{
stopwatch.Stop();
Console.WriteLine(a + "花费时间{0}", stopwatch.Elapsed.ToString());
break;
}
}
int[] arr1 = { 1, 3, 5, 6, 8, 9, 10, 66, 66, 55, 88, 66, 22, 55, 581, 1};
int[] arr2 = { 1,4, 5,7, 8, 55, 10, 66, 66,};
List<int> list = new List<int>();
list.AddRange(arr1);
list.AddRange(arr2);
list.Sort();
foreach(var l in list)
{
Console.WriteLine(l);
}
后缀表达式简介
中缀表达式:
通常,算术表达式写作中缀表达式,,什么是中缀表达式呢?中缀表达式就是:操作符位于操作数之间。如下形式:<操作数><操作符><操作数>例如表达式:1+2*3, 计算时,我们根据表达式的优先规则来计算。其结果是7而不是9。
代码有点长,已经经过测试,放上跟栈有关的核心代码段,如下:
public int evaluate(String expr)
{
int op1, op2, result = 0;
String token;
//将字符串分解,/s 匹配任何空白字符,包括空格、制表符、换页符等。
String[] tokenizer = expr.Split(" ");
for (int x = 0; x < tokenizer.Length; x++)
{
Console.WriteLine(tokenizer[x] + " ");//输出
token = tokenizer[x];
if (isOperator(token))
{//判断是操作符,则出栈两个操作数
op2 = stack.Pop();
op1 = stack.Pop();
result = evalSingleOp(token[0], op1, op2);//计算结果
stack.Push(result);//把计算结果压入栈中
}
else
{
stack.Push( int.Parse(token));//压入操作数
}
}
return result;
}
private bool isOperator(String token)
{
return (token.Equals("+") || token.Equals("-") ||
token.Equals("*") || token.Equals("/"));
}
Stack<int> arr1 = new Stack<int>();
arr1.Push(9);
arr1.Push(3);
arr1.Push(4);
arr1.Push(7);
arr1.Push(2);
public Stack<int> StackSort(Stack<int> arr)
{
if (arr.Count==0)
{
return new Stack<int>();
}
Stack<int> newStack = new Stack<int>();
int top = arr.Pop();
newStack.Push(top);
while (arr.Count>0)
{
int first = arr.Pop(); //拿出第一个
while (newStack.Count > 0 && first > newStack.Peek())
{
int temp = newStack.Pop();
arr.Push(temp);
}
newStack.Push(first);
}
while(newStack.Count>0)
{
int temp = newStack.Pop();
arr.Push(temp);
}
return arr;
}
设计一个算法,判断用户输入的表达式中括号是否匹配,表达式中可能含有圆括号、中括号和大括号。
bool CheckBlancedParentheses(string ch)
{
char[] arr = ch.ToCharArray();
if (0 == arr.Length)
return false;
Stack<char> stack=new Stack<char>();
for(int i=0;i<arr.Length;i++)
{
if ('(' == arr[i] || '[' == arr[i] || '{' == arr[i])
stack.Push(arr[i]);
else if (')' == arr[i])
{
if (stack.Count == 0)
return false;
else if ('(' != stack.Peek())
return false;
else stack.Pop();
}
else if (']' == arr[i])
{
if (stack.Count == 0)
return false;
else if ('[' != stack.Peek())
return false;
else stack.Pop();
}
else if ('}' == arr[i])
{
if (stack.Count== 0)
return false;
else if ('{' != stack.Peek())
return false;
else stack.Pop();
}
}
if (stack.Count>0)
return true;
return false;
}
Stack stack1 = new Stack();
Stack stack2 = new Stack();
public void Push(Object o)
{
stack1.Push(o);
}
public Object Pop()
{
Object o = null;
if (stack2.Count == 0)
{
//把stack1的数据放入stack2,留下最后一个数据
while (stack1.Count > 1)
{
stack2.Push(stack1.Pop());
}
if (stack1.Count == 1)
{
//把stack1的留下的那个数据返回出去
o = stack1.Pop();
}
}
else
{
o = stack2.Pop();
}
return o;
}
Queue<int> queue1 = new Queue<int>();
Queue<int> queue2 = new Queue<int>();
public void Push(int o)
{
queue1.Enqueue(o);
}
public int Pop()
{
int num = 0;
while (queue1.Count > 1)
{
queue2.Enqueue(queue1.Dequeue());
}
if (queue1.Count == 1)
{
//把queue1的留下的那个数据返回出去
num = queue1.Dequeue();
while (queue2.Count > 0)
{
queue1.Enqueue(queue2.Dequeue());
}
}
return num;
}
public Queue<int> ReversalQueue(Queue<int> queue ,int k)
{
Queue<int> queue2 = new Queue<int>();
if (queue.Count == 0) return queue2;
Stack<int> stack = new Stack<int>();
for(int i=0;i<k;i++)
{
stack.Push(queue.Dequeue());
}
while(stack.Count>0)
{
queue2.Enqueue(stack.Pop());
}
while(queue.Count>0)
{
queue2.Enqueue(queue.Dequeue());
}
return queue2;
}
放上核心代码,感兴趣的可以在博客园里面搜一下,很多博友有介绍
public LinkNode<T> Reverse(LinkNode<T> node1, LinkNode<T> node2)
{
bool head= false;
if (node1 == this.Head) head = true;
LinkNode<T> tmp = node2.Next;
node2.Next = node1;
if (head) node1.Next = null;
if (tmp == null) {
return node2; }
else
{
return Reverse(node2, tmp);
}
}
涉及到指针
找到使用地方再回头来补,或者看上一篇文章,链接中是其他博友的介绍并附有代码
找到使用地方再回头来补,或者看上一篇文章,链接中是其他博友的介绍并附有代码
找到使用地方再回头来补,或者看上一篇文章,链接中是其他博友的介绍并附有代码
先看源码
// buckets是哈希表,用来存放Key的Hash值
// entries用来存放元素列表
// count是元素数量
private void Insert(TKey key, TValue value, bool add)
{
if (key == null)
{
throw new ArgumentNullException(key.ToString());
}
// 首先分配buckets和entries的空间
if (buckets == null) Initialize(0);
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; // 计算key值对应的哈希值(HashCode)
int targetBucket = hashCode % buckets.Length; // 对哈希值求余,获得需要对哈希表进行赋值的位置
#if FEATURE_RANDOMIZED_STRING_HASHING
int collisionCount = 0;
#endif
// 处理冲突的处理逻辑
for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
{
if (add)
{
throw new ArgumentNullException();
}
entries[i].value = value;
version++;
return;
}
#if FEATURE_RANDOMIZED_STRING_HASHING
collisionCount++;
#endif
}
int index; // index记录了元素在元素列表中的位置
if (freeCount > 0)
{
index = freeList;
freeList = entries[index].next;
freeCount--;
}
else
{
// 如果哈希表存放哈希值已满,则重新从primers数组中取出值来作为哈希表新的大小
if (count == entries.Length)
{
Resize();
targetBucket = hashCode % buckets.Length;
}
// 大小如果没满的逻辑
index = count;
count++;
}
// 对元素列表进行赋值
entries[index].hashCode = hashCode;
entries[index].next = buckets[targetBucket];
entries[index].key = key;
entries[index].value = value;
// 对哈希表进行赋值
buckets[targetBucket] = index;
version++;
#if FEATURE_RANDOMIZED_STRING_HASHING
if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
{
comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer(comparer);
Resize(entries.Length, true);
}
#endif
}
快速原因 :使用哈希表来存储元素对应的位置,然后我们可以通过哈希值快速地从哈希表中定位元素所在的位置索引,从而快速获取到key对应的Value值(可以根据上一篇介绍理解)
写文章很少有完美的说法,上一篇文章在发布之后,我又新增修改了很多东西,有点"缝缝补补又三年"的感觉。这篇(下)也需要再进行遗漏查缺,哪天来想法了(例如哈希,二叉树,B树),又来进行完善。如果觉的可以,请关注一下。 写博文的主要目的是完善巩固自己的知识体系,翻阅大量文章来学习的一个过程,目的并不是为了赞赏,不信你看看赞赏,是否看到了信仰。 该系列上中下基本终于结束,对于大神来说,数据结构就是小菜一碟(数据结构也不止我写的这么点),但对很多来人,之前对于数据结构的3W都没怎么花心思去想,如果有人问到了,是不是很惭愧。接下来,我会继续巩固基础(这个个人觉的非常重要)和研究框架以及微服务,继续努力!
标签:通过 tin exp 数组 ddr head 方法 round max
原文地址:https://www.cnblogs.com/zhan520g/p/10222894.html