跟上一篇《數據結構,你還記得嗎(中)》目錄進行一一對應,以此來提高理解。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都沒怎麼花心思去想,若是有人問到了,是否是很慚愧。接下來,我會繼續鞏固基礎(這個我的覺的很是重要)和研究框架以及微服務,繼續努力!