algorithmpagination# Algorithm / pseudo-code to create paging links?

Can someome provide code or pseudo-code for how the paging links on StackOverflow are generated?

I keep racking my brain but can't think of a decent way to build the dynamic links that always show the 2 pages around the current, plus the first and last.

Example: `1 ... 5 6 7 ... 593`

Solution

There are several other answers already, but I'd like to show you the approach I took to solve it: First, let's check out how Stack Overflow handles normal cases and edge cases. Each of my pages displays 10 results, so to find out what it does for 1 page, find a tag that has less than 11 entries: usability works today. We can see nothing is displayed, which makes sense.

How about 2 pages? Find a tag that has between 11 and 20 entries (emacs works today). We see: "**1** 2 Next" or "Prev 1 **2**", depending on which page we're on.

3 pages? "**1** 2 3 ... 3 Next", "Prev 1 **2** 3 Next", and "Prev 1 ... 2 **3**". Interestingly, we can see that Stack Overflow itself doesn't handle this edge case very well: it should display "**1** 2 ... 3 Next"

4 pages? "**1** 2 3 ... 4 Next", "Prev 1 **2** 3 ... 4 Next", "Prev 1 ... 2 **3** 4 Next" and "Prev 1 ... 3 **4**"

Finally let's look at the general case, N pages: "**1** 2 3 ... N Next", "Prev 1 **2** 3 ... N Next", "Prev 1 ... 2 **3** 4 ... N Next", "Prev 1 ... 3 **4** 5 ... N Next", etc.

Let's generalize based on what we've seen: The algorithm seems to have these traits in common:

- If we're not on the first page, display link to Prev
- Always display the first page number
- Always display the current page number
- Always display the page before this page, and the page after this page.
- Always display the last page number
- If we're not on the last page, display link to Next

Let's ignore the edge case of a single page and make a good first attempt at the algorithm: (As has been mentioned, the code to actually print out the links would be more complicated. Imagine each place we place a page number, Prev or Next as a function call that will return the correct URL.)

```
function printPageLinksFirstTry(num totalPages, num currentPage)
if ( currentPage > 1 )
print "Prev"
print "1"
print "..."
print currentPage - 1
print currentPage
print currentPage + 1
print "..."
print totalPages
if ( currentPage < totalPages )
print "Next"
endFunction
```

This function works ok, but it doesn't take into account whether we're near the first or last page. Looking at the above examples, we only want to display the ... if the current page is two or more away.

```
function printPageLinksHandleCloseToEnds(num totalPages, num currentPage)
if ( currentPage > 1 )
print "Prev"
print "1"
if ( currentPage > 2 )
print "..."
if ( currentPage > 2 )
print currentPage - 1
print currentPage
if ( currentPage < totalPages - 1 )
print currentPage + 1
if ( currentPage < totalPages - 1 )
print "..."
print totalPages
if ( currentPage < totalPages )
print "Next"
endFunction
```

As you can see, we have some duplication here. We can go ahead and clean that up for readibility:

```
function printPageLinksCleanedUp(num totalPages, num currentPage)
if ( currentPage > 1 )
print "Prev"
print "1"
if ( currentPage > 2 )
print "..."
print currentPage - 1
print currentPage
if ( currentPage < totalPages - 1 )
print currentPage + 1
print "..."
print totalPages
if ( currentPage < totalPages )
print "Next"
endFunction
```

There are only two problems left. First, we don't print out correctly for one page, and secondly, we'll print out "1" twice if we're on the first or last page. Let's clean those both up in one go:

```
function printPageLinksFinal(num totalPages, num currentPage)
if ( totalPages == 1 )
return
if ( currentPage > 1 )
print "Prev"
print "1"
if ( currentPage > 2 )
print "..."
print currentPage - 1
if ( currentPage != 1 and currentPage != totalPages )
print currentPage
if ( currentPage < totalPages - 1 )
print currentPage + 1
print "..."
print totalPages
if ( currentPage < totalPages )
print "Next"
endFunction
```

Actually, I lied: We have one remaining issue. When you have at least 4 pages and are on the first or last page, you get an extra page in your display. Instead of "**1** 2 ... 10 Next" you get "**1** 2 3 ... 10 Next". To match what's going on at Stack Overflow exactly, you'll have to check for this situation:

```
function printPageLinksFinalReally(num totalPages, num currentPage)
if ( totalPages == 1 )
return
if ( currentPage > 1 )
print "Prev"
print "1"
if ( currentPage > 2 )
print "..."
if ( currentPage == totalPages and totalPages > 3 )
print currentPage - 2
print currentPage - 1
if ( currentPage != 1 and currentPage != totalPages )
print currentPage
if ( currentPage < totalPages - 1 )
print currentPage + 1
if ( currentPage == 1 and totalPages > 3 )
print currentPage + 2
print "..."
print totalPages
if ( currentPage < totalPages )
print "Next"
endFunction
```

I hope this helps!

- Difference between back tracking and dynamic programming
- How can we optimize this algorithm from O(N ** 2) to better complexity in order to pass performance test?
- How do I predict the required size of a Base32 Decode output?
- Reversing AND Bitwise
- Why does my binary search need an extra comparison? log2(N)+1
- How to build a trie for finding exact phonetic matches, sorted globally by weight, and paginated? (Building off this example)
- What is the Time Complexity and Space Complexity of extending a string according to a rule?
- Skyscraper puzzle algorithm
- Check if all elements in a list are equal
- Bitwise Interval Arithmetic
- fast algorithm for drawing filled circles?
- How to find distance from the latitude and longitude of two locations?
- Determine if two rectangles overlap each other?
- Randomly Splitting a Graph according to Conditions
- Maximize distance while pushing crates
- Free a binary tree without recursion
- How can I estimate number of nodes in given tree structure?
- Explanation of class Definition for Binary Trees in leetcode
- Procedural Generation of 2D Rooms
- Is there an algorithm to find the closest element to X in an unsorted array in Ω(logN)?
- Advanced Java idiom for 2+ classes implementing a generic interface
- Is there any algorithm in c# to singularize - pluralize a word?
- Number of Common sub sequences of two strings
- Trying to solve problem 19 on Euler Project
- is a "non-decreasing" sequence "increasing"?
- Is it possible to get the original value of a number, after several multiplications **with overflow**?
- Algorithm to determine the highest and lowest possible finishing position of a team in a league
- Algorithm to calculate the number of divisors of a given number
- Rolling or sliding window iterator?
- best way to pick a random subset from a collection?