{"id":242,"date":"2021-01-09T22:33:46","date_gmt":"2021-01-09T22:33:46","guid":{"rendered":"http:\/\/windows.emacslisp.com\/?p=242"},"modified":"2021-01-09T22:35:07","modified_gmt":"2021-01-09T22:35:07","slug":"priorityqueue-in-c","status":"publish","type":"post","link":"http:\/\/windows.emacslisp.com\/index.php\/2021\/01\/09\/priorityqueue-in-c\/","title":{"rendered":"PriorityQueue in C#"},"content":{"rendered":"<p>PriorityQueue is a binary heap. Heap is commonly used algorithm. in some area such Graph shortest path and minimum spanning tree, it is very helpful.<\/p>\n<p>both Java and C++ has PriorityQueue, but C# don&#8217;t have. <\/p>\n<p>Here is a version of PriorityQueue<\/p>\n<pre lang=\"csharp\" line=\"1\"> \r\n\/\/\/ <summary>\r\n    \/\/\/ \r\n    \/\/\/ <\/summary>\r\n    \/\/\/ <typeparam name=\"T\"><\/typeparam>\r\n    public class PriorityQueue<T> where T : IComparable<T>\r\n    {\r\n        private List<T> data;\r\n        private bool isMaxHeap = false; \r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        public PriorityQueue()\r\n        {\r\n            this.data = new List<T>();\r\n        }\r\n\r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        \/\/\/ <param name=\"isMaxHeap\"><\/param>\r\n        public PriorityQueue(bool isMaxHeap)\r\n        {\r\n            this.data = new List<T>();\r\n            this.isMaxHeap = isMaxHeap;\r\n        }\r\n\r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        \/\/\/ <param name=\"item\"><\/param>\r\n        public void Enqueue(T item)\r\n        {\r\n            data.Add(item);\r\n            int ci = data.Count - 1; \/\/ child index; start at end\r\n            while (ci > 0)\r\n            {\r\n                int pi = (ci - 1) \/ 2; \/\/ parent index\r\n                if(isMaxHeap)\r\n                {\r\n                    if (data[ci].CompareTo(data[pi]) <= 0) break;\r\n                } else if (data[ci].CompareTo(data[pi]) >= 0)\r\n                    break; \/\/ child item is larger than (or equal) parent so we're done\r\n                T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;\r\n                ci = pi;\r\n            }\r\n        }\r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        \/\/\/ <returns><\/returns>\r\n        public T Dequeue()\r\n        {\r\n            \/\/ assumes pq is not empty; up to calling code\r\n            int li = data.Count - 1; \/\/ last index (before removal)\r\n            T frontItem = data[0];   \/\/ fetch the front\r\n            data[0] = data[li];\r\n            data.RemoveAt(li);\r\n\r\n            --li; \/\/ last index (after removal)\r\n            int pi = 0; \/\/ parent index. start at front of pq\r\n            while (true)\r\n            {\r\n                int ci = pi * 2 + 1; \/\/ left child index of parent\r\n                if (ci > li) break;  \/\/ no children so done\r\n                int rc = ci + 1;     \/\/ right child\r\n                if (isMaxHeap)\r\n                {\r\n                    if (rc <= li &#038;&#038; data[rc].CompareTo(data[ci]) >= 0) \/\/ if there is a rc (ci + 1), and it is smaller than left child, use the rc instead\r\n                        ci = rc;\r\n                    if (data[pi].CompareTo(data[ci]) >= 0) break; \/\/ parent is smaller than (or equal to) smallest child so done\r\n                }\r\n                else\r\n                {\r\n\r\n                    if (rc <= li &#038;&#038; data[rc].CompareTo(data[ci]) < 0) \/\/ if there is a rc (ci + 1), and it is smaller than left child, use the rc instead\r\n                        ci = rc;\r\n                    if (data[pi].CompareTo(data[ci]) <= 0) break; \/\/ parent is smaller than (or equal to) smallest child so done\r\n                }\r\n\r\n                T tmp = data[pi]; data[pi] = data[ci]; data[ci] = tmp; \/\/ swap parent and child\r\n                pi = ci;\r\n            }\r\n            return frontItem;\r\n        }\r\n\r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        \/\/\/ <returns><\/returns>\r\n        public T Peek()\r\n        {\r\n            T frontItem = data[0];\r\n            return frontItem;\r\n        }\r\n\r\n        \/\/\/ <summary>\r\n        \/\/\/ \r\n        \/\/\/ <\/summary>\r\n        \/\/\/ <returns><\/returns>\r\n        public int Count()\r\n        {\r\n            return data.Count;\r\n        }\r\n\r\n        public override string ToString()\r\n        {\r\n            string s = \"\";\r\n            for (int i = 0; i < data.Count; ++i)\r\n                s += data[i].ToString() + \" \";\r\n            s += \"count = \" + data.Count;\r\n            return s;\r\n        }\r\n\r\n        public bool IsConsistent()\r\n        {\r\n            \/\/ is the heap property true for all data?\r\n            if (data.Count == 0) return true;\r\n            int li = data.Count - 1; \/\/ last index\r\n            for (int pi = 0; pi < data.Count; ++pi) \/\/ each parent index\r\n            {\r\n                int lci = 2 * pi + 1; \/\/ left child index\r\n                int rci = 2 * pi + 2; \/\/ right child index\r\n\r\n                if (lci <= li &#038;&#038; data[pi].CompareTo(data[lci]) > 0) return false; \/\/ if lc exists and it's greater than parent then bad.\r\n                if (rci <= li &#038;&#038; data[pi].CompareTo(data[rci]) > 0) return false; \/\/ check the right child too.\r\n            }\r\n            return true; \/\/ passed all checks\r\n        } \/\/ IsConsistent\r\n    }\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>PriorityQueue is a binary heap. Heap is commonly used algorithm. in some area such Graph shortest path and minimum spanning tree, it is very helpful. both Java and C++ has PriorityQueue, but C# don&#8217;t have. Here is a version of &hellip; <a href=\"http:\/\/windows.emacslisp.com\/index.php\/2021\/01\/09\/priorityqueue-in-c\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"_links":{"self":[{"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/posts\/242"}],"collection":[{"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/comments?post=242"}],"version-history":[{"count":3,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/posts\/242\/revisions"}],"predecessor-version":[{"id":245,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/posts\/242\/revisions\/245"}],"wp:attachment":[{"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/media?parent=242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/categories?post=242"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/windows.emacslisp.com\/index.php\/wp-json\/wp\/v2\/tags?post=242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}