跟上一篇《数据结构,你还记得吗(中)》目录进行一一对应,以此来提高理解。html
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();node
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); } }
涉及到指针数据结构
找到使用地方再回头来补,或者看上一篇文章,连接中是其余博友的介绍并附有代码框架
找到使用地方再回头来补,或者看上一篇文章,连接中是其余博友的介绍并附有代码dom
找到使用地方再回头来补,或者看上一篇文章,连接中是其余博友的介绍并附有代码编辑器
先看源码函数
// 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都没怎么花心思去想,若是有人问到了,是否是很惭愧。接下来,我会继续巩固基础(这个我的觉的很是重要)和研究框架以及微服务,继续努力!