Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Circular linked list puzzle

Circular linked list puzzle

Scheduled Pinned Locked Moved C / C++ / MFC
questiondata-structures
14 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M melwyn

    Hi, Nope not homework. It was an interview question of a friend. I think I missed out some details when I gave the puzzle. We need to determine if the linked list is properly circular or not. Consider this linked list of 3 nodes A->B->C and C points back to B instead of A. Now according to your algorithm both the pointers will converge on some node, but the linked list is not a proper circular linked list. I was thinking more on the lines of storing the address of each node in some table as I parse down the list. Then if i come across a node whose entry already exists in the table and I haven't passed the starting node twice then it means there is some problem in the list. However my solution doesn't satisfy the condition of 2 pointers etc. -Mel

    I Offline
    I Offline
    Ian Darling
    wrote on last edited by
    #4

    melwyn wrote: We need to determine if the linked list is properly circular or not. That wasn't suggested by your original post - it implied that there was a circle of some sort in the linked list, not that the whole list was either circular or straight :-) If it's properly circular, you only need to move a single pointer, with a second one pointing at the start, and you just wait for it to come around again (or hit the termination node). However, this means you can't determine if your list is "improperly" circular, as the moving pointer will get stuck in a loop and never return to the start. You can merge the two methods and use three pointers (start, slow and fast), which allows you to identify "properly", "improperly" and "not" circular lists, which would seem to me to be more useful. (Thinking about it, I'm sure Knuth would have solved this. I'll have to look it up properly tonight :-)) -- Ian Darling "The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

    J 1 Reply Last reply
    0
    • M melwyn

      Hi, Here's a puzzle. I have a linked list which may or may-not be circular. Using 2 pointers which have to be moving at any given point of time how do i determine if the linked list is circular? -Mel

      R Offline
      R Offline
      Ravi Bhavnani
      wrote on last edited by
      #5

      Aha! (Another) classic Microsoft interview question! :) /ravi Let's put "civil" back in "civilization" Home | Articles | Freeware | Music ravib@ravib.com

      J M 2 Replies Last reply
      0
      • I Ian Darling

        melwyn wrote: We need to determine if the linked list is properly circular or not. That wasn't suggested by your original post - it implied that there was a circle of some sort in the linked list, not that the whole list was either circular or straight :-) If it's properly circular, you only need to move a single pointer, with a second one pointing at the start, and you just wait for it to come around again (or hit the termination node). However, this means you can't determine if your list is "improperly" circular, as the moving pointer will get stuck in a loop and never return to the start. You can merge the two methods and use three pointers (start, slow and fast), which allows you to identify "properly", "improperly" and "not" circular lists, which would seem to me to be more useful. (Thinking about it, I'm sure Knuth would have solved this. I'll have to look it up properly tonight :-)) -- Ian Darling "The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

        J Offline
        J Offline
        Jorgen Sigvardsson
        wrote on last edited by
        #6

        Your algorithm will work for non-proper linked lists as well. Start at the beginning of the list*. If there is a non-proper cycle in it, your pointers will indeed catch up with eachother sooner or later. Whip out your pen and paper and see for your self :)

        le* first = list->head;
        le* second = list->head ? list->head->next;

        while(second != first && second != NULL) {
        second = second->next;
        if(second != first && second != NULL) {
        second = second->next;
        first = first->next;
        }
        }

        if(second == NULL)
        printf("No cycle\n");
        else
        printf("There is a cycle at %p (v = %d)\n", second, second->value);

        * Assume you don't start at the beginning of the list and there exists a cycle on the list prior to your start but no loop back to it. Then it is impossible to detect that cycle, since there is no way back to it. The problem stated a linked list, which I assume is a singly linked list, as doubly linked lists are usually named just that. A doubly linked list can be a bit trickier. Especially if for some i: i->prev->next != i. Not really sure about the implications of that as I don't feel a particular pressure to find out, but I'm sure it would make the problem a bit more fun. :) -- I can't resist a touch of evil.

        I M 2 Replies Last reply
        0
        • R Ravi Bhavnani

          Aha! (Another) classic Microsoft interview question! :) /ravi Let's put "civil" back in "civilization" Home | Articles | Freeware | Music ravib@ravib.com

          J Offline
          J Offline
          Jorgen Sigvardsson
          wrote on last edited by
          #7

          Have you been an interviewee, or are you an interviewer? :) -- I can't resist a touch of evil.

          M 1 Reply Last reply
          0
          • I Ian Darling

            (mmmm, smells like homework) Given you don't know whether it is or not, I would suggest you need to have a "slow" pointer and a "fast" pointer. For each time you move the slow pointer a single node along the linked list, you move the fast pointer on two nodes. If there is a circle, once both pointers are inside it the fast pointer will eventually "catch up" to the slow one, and they will both point at the same node (note that this isn't necessarily the "start" node of the circle, just a node within it). If the fast pointer reaches a terminating node, then there is (obviously) no circle. The performance characteristics aren't fantastic, but the algorithm should be sound. -- Ian Darling "The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

            T Offline
            T Offline
            Terry ONolley
            wrote on last edited by
            #8

            Ian Darling wrote: (mmmm, smells like homework) It can't be homework! If it were homework, the poster would be smart enough to figure this out - since they were also clever enough to pose it as a "puzzle" instead of homework! :)


            Have you answered an MTQ? Check out the stats!

            M 1 Reply Last reply
            0
            • J Jorgen Sigvardsson

              Your algorithm will work for non-proper linked lists as well. Start at the beginning of the list*. If there is a non-proper cycle in it, your pointers will indeed catch up with eachother sooner or later. Whip out your pen and paper and see for your self :)

              le* first = list->head;
              le* second = list->head ? list->head->next;

              while(second != first && second != NULL) {
              second = second->next;
              if(second != first && second != NULL) {
              second = second->next;
              first = first->next;
              }
              }

              if(second == NULL)
              printf("No cycle\n");
              else
              printf("There is a cycle at %p (v = %d)\n", second, second->value);

              * Assume you don't start at the beginning of the list and there exists a cycle on the list prior to your start but no loop back to it. Then it is impossible to detect that cycle, since there is no way back to it. The problem stated a linked list, which I assume is a singly linked list, as doubly linked lists are usually named just that. A doubly linked list can be a bit trickier. Especially if for some i: i->prev->next != i. Not really sure about the implications of that as I don't feel a particular pressure to find out, but I'm sure it would make the problem a bit more fun. :) -- I can't resist a touch of evil.

              I Offline
              I Offline
              Ian Darling
              wrote on last edited by
              #9

              Jörgen Sigvardsson wrote: Your algorithm will work for non-proper linked lists as well. I know that, that's what I originally set out to do (and I have the scribbles to prove it) :-D The debate was over truly circular linked lists :-) Jörgen Sigvardsson wrote: A doubly linked list can be a bit trickier. Especially if for some i: i->prev->next != i. Not really sure about the implications of that as I don't feel a particular pressure to find out, but I'm sure it would make the problem a bit more fun. :laugh: Yes. Couldn't find anything about this sort of problem in Knuths books at all - I'll have to write my own "solve stupid linked-list puzzles" book ;P -- Ian Darling "The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

              J 1 Reply Last reply
              0
              • I Ian Darling

                Jörgen Sigvardsson wrote: Your algorithm will work for non-proper linked lists as well. I know that, that's what I originally set out to do (and I have the scribbles to prove it) :-D The debate was over truly circular linked lists :-) Jörgen Sigvardsson wrote: A doubly linked list can be a bit trickier. Especially if for some i: i->prev->next != i. Not really sure about the implications of that as I don't feel a particular pressure to find out, but I'm sure it would make the problem a bit more fun. :laugh: Yes. Couldn't find anything about this sort of problem in Knuths books at all - I'll have to write my own "solve stupid linked-list puzzles" book ;P -- Ian Darling "The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

                J Offline
                J Offline
                Jorgen Sigvardsson
                wrote on last edited by
                #10

                Ian Darling wrote: Couldn't find anything about this sort of problem in Knuths books at all - I'll have to write my own "solve stupid linked-list puzzles" book Be sure to write your own imaginary CPU before you do! ;) -- I'm your turbo lover. Better run for cover![^]

                1 Reply Last reply
                0
                • T Terry ONolley

                  Ian Darling wrote: (mmmm, smells like homework) It can't be homework! If it were homework, the poster would be smart enough to figure this out - since they were also clever enough to pose it as a "puzzle" instead of homework! :)


                  Have you answered an MTQ? Check out the stats!

                  M Offline
                  M Offline
                  melwyn
                  wrote on last edited by
                  #11

                  Believe me it's not homework. The professors (in my college atleast) weren't that smart enough to pose such type of puzzles :) ...also if they did pose the problem, they would have to know the solution :) . Btw, I graduated over 4 years ago. :)

                  1 Reply Last reply
                  0
                  • R Ravi Bhavnani

                    Aha! (Another) classic Microsoft interview question! :) /ravi Let's put "civil" back in "civilization" Home | Articles | Freeware | Music ravib@ravib.com

                    M Offline
                    M Offline
                    melwyn
                    wrote on last edited by
                    #12

                    No, not Microsoft, but it is in the top 5 software companies in the world. Btw, do you know other Microsoft interview questions? :)

                    1 Reply Last reply
                    0
                    • J Jorgen Sigvardsson

                      Have you been an interviewee, or are you an interviewer? :) -- I can't resist a touch of evil.

                      M Offline
                      M Offline
                      melwyn
                      wrote on last edited by
                      #13

                      I have been the former a few times. Sometimes I just go for an interview to test my skills and get some interesting puzzles to solve :).

                      1 Reply Last reply
                      0
                      • J Jorgen Sigvardsson

                        Your algorithm will work for non-proper linked lists as well. Start at the beginning of the list*. If there is a non-proper cycle in it, your pointers will indeed catch up with eachother sooner or later. Whip out your pen and paper and see for your self :)

                        le* first = list->head;
                        le* second = list->head ? list->head->next;

                        while(second != first && second != NULL) {
                        second = second->next;
                        if(second != first && second != NULL) {
                        second = second->next;
                        first = first->next;
                        }
                        }

                        if(second == NULL)
                        printf("No cycle\n");
                        else
                        printf("There is a cycle at %p (v = %d)\n", second, second->value);

                        * Assume you don't start at the beginning of the list and there exists a cycle on the list prior to your start but no loop back to it. Then it is impossible to detect that cycle, since there is no way back to it. The problem stated a linked list, which I assume is a singly linked list, as doubly linked lists are usually named just that. A doubly linked list can be a bit trickier. Especially if for some i: i->prev->next != i. Not really sure about the implications of that as I don't feel a particular pressure to find out, but I'm sure it would make the problem a bit more fun. :) -- I can't resist a touch of evil.

                        M Offline
                        M Offline
                        melwyn
                        wrote on last edited by
                        #14

                        Jörgen Sigvardsson wrote: The problem stated a linked list, which I assume is a singly linked list, as doubly linked lists are usually named just that. Actually the interviewer had mentioned that the linked list could be considered as doubly linked, if it could help solve the problem in any way.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups