I am trying to write an insertion sort method but I am unable to seal the deal. Below is the code I have so far and I just cant seem to get the algorithm to work properly. The RecordList class contains all the methods for the linked list. Specificaly, Sort() works with a user defined object Student in which the students are sorted by ID numbers
public class RecordList {
private Link first; //ref to first item
private Link last; //ref to last item
int count = 0; //count number of elms in list
//constructor
public RecordList(){
first=null;
last=null;
}
//is empty
public boolean isEmpty(){
return first==null;
}
//insert first
public void insertFirst(Student dd){
count++;
Link newLink = new Link(dd); // make new link
if( isEmpty() ){ // if empty list,
last = newLink; // newLink <-- last
}
else{
first.previous = newLink; // newLink <-- old first
newLink.next = first; // newLink --> old first
first = newLink; // first --> newLink
}
}
//insert last
public void insertLast(Student dd){
count++;
Link newLink = new Link(dd); // make new link
if( isEmpty() ){ // if empty list,
first = newLink; // first --> newLink
}
else{
last.next = newLink; // old last --> newLink
newLink.previous = last; // old last <-- newLink
}
last = newLink; // newLink <-- last
}
//delete first
//ASSUMES NOT EMPTY
public Link deleteFirst(){
count--;
Link temp = first;
if(first.next == null){ // if only one item
last = null; // null <-- last
}
else{
first.next.previous = null; // null <-- old next
first = first.next; // first --> old next
}
return temp;
}
//delete last
//ASSUMES NOT EMPTY
public Link deleteLast(){
count--;
Link temp = last;
if(first.next == null){ // if only one item
first = null; // first --> null
}
else{
last.previous.next = null; // old previous --> null
last = last.previous; // old previous <-- last
}
return temp;
}
public boolean insertAfter(Student key, Student dd){ // (assumes non-empty list)
Link current = first; // start at beginning
while(current.dData != key){ // until match is found,
current = current.next; // move to next link
if(current == null){
return false; // didn’t find it
}
}
Link newLink = new Link(dd); // make new link
if(current==last){ // if last link,
newLink.next = null; // newLink --> null
last = newLink; // newLink <-- last
}
else{ // not last link,
newLink.next = current.next; // newLink --> old next
// newLink <-- old next
current.next.previous = newLink;
}
newLink.previous = current; // old current <-- newLink
current.next = newLink; // old current --> newLink
return true; // found it, did insertion
}
//self algorithm
public void Sort(){
Link marker = first;
Link current = null;
Link temp;
//if more than one elm sort
if(count > 1){
marker = marker.next;
//outer loop
//until end of list
while(marker != null){
current = marker.previous;
temp = marker;
//inner loop
//until position found
while(temp.dData.getID() > current.dData.getID()){
if(current == marker.previous){
marker = marker.next;
}
else{
marker = marker.next;
//remove temp from original position
if(temp.next == null){
last = temp.previous;
last.next = null;
}
else{
temp.previous.next = temp.next;
temp.next.previous = temp.previous;
}
//check to see if inserting to first elm or not
if(current == null){
//insert temp to first
//*****CHECK ALGORITHM*****\\
}
else{
//insert temp to current.next
temp.next = current.next;
temp.previous = current;
current.next.previous = temp;
current.next = temp;
}
}
}
//while/else DOES not work
else{
//if while condition not met
current = current.previous;
if(current == null){
//break to outer
}
else{
//break to inner
}
}
}
}
}
//display
#Override
public String toString(){
String s="";
Link current = first;
while(current != null){
s += current.dData+"\n"+"\n";
current = current.nextLink();
}
return s;
}
}
Sorry but your code looks like unnecessarily complicated. Also, your code contains a lot of more code than just 'sorting' on which your question is based. If "sorting" is your point of concern, try this. Otherwise feel free to downvote this answer, because Stack Overflow is only here to help you clear your concepts and then debug your own code.
This is the short and sweet code for Insertion sort (using array and JavaScript for easily checking in browser console). Check it in your browser console. And once you are clear with the idea, extend it for Linked List. Try to keep it simple like this and you will find your bug,
var a = [3,1,5,57,9,12,91,45,65,67,89,21,13,56,76,32,77,89,71];
console.log('array before sort...' + a);
//The Insertion Sort
for(var i=1; i<a.length; i++) {
var j = i-1;
var key = a[i];
while(j>=0 && a[j] > key) {
a[j+1] = a[j];
j--;
}
a[j+1] = key;
}
console.log('array after sort...' + a);
Just press F12 to open console in your browser. Paste this code and press Enter. Play with it to understand more.
Good Luck !!!
Related
Can anyone help on what's wrong with my code? Only the first input number shows up when I run it (it doesn't create a sorted list), the delete command isn't working, and the 'true' 'false' in exists command doesn't show up. My output should match the given sample I put at the end.
The areas I had to fill in to make the code work are the areas after the TODOTODOTODO symbols which would be 44-61, 75-83, 97-105. I'm not sure where I went wrong in those areas and why it is not working correctly to give the desired output?
import java.util.Scanner;
// Defines the a Sorted Set collection and implements a driver program in main
public class SortedSet {
// Define a basic element of a linked list
private class LinkedNode {
int x; // Value stored in the node
LinkedNode next; // Reference to the next node in the list
}
LinkedNode front = null; // Reference to the front of the singly linked list
// Adds the integer x to the collection.
// The resulting collection is sorted in increasing order and
// does not contain any duplicate values.
public void add(int x) {
// Initialize a new node to be added to the collection
LinkedNode newNode = new LinkedNode();
LinkedNode cur = front;
newNode.x = x;
// Check if list is empty
if (cur == null) {
front = newNode;
}
// If list is not empty, check if node should be placed in front
else if (front != null) {
if (newNode.x < front.x) {
newNode.next = front;
front = newNode;
}
// If not in front, check for the middle or the end, or duplicate.
else {
// <TODO><TODO><TODO>
LinkedNode temp = cur;
LinkedNode prev = cur;
int middle = x;
while (temp != null) {
if(temp.x > newNode.x) {
middle = 1;
newNode.next = temp;
prev.next = newNode;
}
prev = temp;
temp = temp.next;
}
if (middle == 0) {
prev = newNode;
}
}
}
}
// Deletes the integer x from the sorted set.
// The remaining collection remains sorted and without duplicates.
public void delete(int x){
// Declare a new reference and initialize it to the front of the list
LinkedNode cur = front;
// Check if list is empty
if (front == null) {
System.out.print("There is nothing to delete!");
} else { // Not empty
// Go through list, checking whether node is in the list, and delete if found
// <TODO><TODO><TODO>
LinkedNode prev = new LinkedNode();
while (cur.x != x && cur != null) {
prev = cur;
cur = cur.next;
}
if (cur != null)
prev.next = cur.next;
}
}
// Returns true if the integer x exists in the sorted set and false otherwise.
public void exists(int x) {
// Declare a new reference and initialize it to the front of the list
LinkedNode cur = front;
// Check if list is empty.
if (front == null) {
System.out.println("false");
}
// If not empty, check for the node.
// <TODO><TODO><TODO>
else {
while (cur != null) {
if (cur.x==x)
return;
cur=cur.next;
}
return;
}
}
// Returns a string representing the sorted set as a space separated list.
public String toString() {
String s = "";
LinkedNode cur = front;
while (cur!=null) {
s+= cur.x + " ";
cur = cur.next;
}
return s;
}
// Driver method
public static void main(String[] args) {
// Declare variables
SortedSet sortedSet = new SortedSet();
Scanner scan = new Scanner(System.in);
String[] tokens;
String command;
int num;
// Print header info
System.out.println("Programming Fundamentals\n"
+ "NAME: Andres Reyes\n"
+ "PROGRAMMING ASSIGNMENT 4\n");
// Enter command loop
while (true) {
// Prompt the user for a command
System.out.print("Enter command: ");
String input = scan.nextLine();
// Parse input
if (input.equals("q")) break; // user quits
tokens = input.split("\\s");
if (tokens.length < 2) continue; // invalid input
command = tokens[0];
num = Integer.parseInt(tokens[1]);
// Execute command
if (command.equals("add")){
sortedSet.add(num);
System.out.println(sortedSet);
} else if (command.equals("del")) {
sortedSet.delete(num);
System.out.println(sortedSet);
} else if (command.equals("exists")) {
sortedSet.exists(num);
} else {
System.out.print("Command does not exist");
}
}
System.out.println("\nGood bye!");
}
}
I made following changes in the add-function and they got it working for me:
// If not in front, check for the middle or the end, or duplicate.
else {
// <TODO><TODO><TODO>
LinkedNode temp = cur.next; // start at cur.next as your temp-variable
LinkedNode prev = cur;
int middle = 0; // set middle to 0
while (temp != null) {
if(temp.x > newNode.x) {
middle = 1;
newNode.next = temp;
prev.next = newNode;
}
prev = temp;
temp = temp.next;
}
if (middle == 0) {
// add node to the end
prev.next = newNode;
}
}
}
You have to start at cur.next as your temp-variable.
As far as I can see, you're not yet checking if there are any duplicate values in your list.
Edit: I didn't work on the exists-method, which is not giving you any output at the moment. The problem is simply that you're generating any output while you're checking if a value exists in your list. You could either write a System.out.print which prints "true" in case the value was found or "false" in case if wasn't. Or you change the return type of the exists-function to boolean, return a boolean according to the result and print the return value.
It might also help you to visualize a linked list to unterstand why you have to change the temp-variable to cur.next. I think https://www.tutorialspoint.com/data_structures_algorithms/linked_lists_algorithm.htm gives a good explaination of the insertion process.
I can give you some hints. The main problem I see with this code is that you really need a reference to the start of the LinkedList (the head) would be the only way to print the list and check for duplicates.
The following should be added to your class
LinkedList head = null; //start of the list
Then you have to update your toString() or you will never print the correct elements in your list no matter what you do. Try this:
public String toString(){
StringBuilder output = new StringBuilder();
LinkedNode current = head;
while(current != null){
output.append(current.x).append(" ");
current = current.next;
}
return output.toString();
}
You have to be really careful when you are appending to a String in a loop because Strings are immutable. Everytime you are appending to a list you are creating a new String. Instead, use StringBuilder.
//s+= cur.x + " ";
Your add method should handle the following cases:
Case 1: List is empty: ( don't forget to set ref to head)
Case 2: new element is great than front of list
Case 3: new element is less than current head
Case 4: new element is less than current and greater than head
I believe I have the code on how to remove an item in a linked list but I'm not sure how I can make it so that all occurrences of a value would be removed. Where would I need to make some changes that would have it check through all the values in the list?
I've tried to make an alternate or a dummy that pointed to the head but I wasn't sure where I was going with that.
public class LinkList {
private Link first; // ref to first link on list
// -------------------------------------------------------------
public LinkList() // constructor
{
first = null; // no links on list yet
}
// -------------------------------------------------------------
public void insertFirst(int id, double dd) {
Link newLink = new Link(id, dd);
newLink.next = first; // it points to old first link
first = newLink; // now first points to this
}
// -------------------------------------------------------------
public Link find(int key) // find link with given key
{ // (assumes non-empty list)
Link current = first; // start at 'first'
while (current.iData != key) // while no match,
{
if (current.next == null) // if end of list,
{
return null; // didn't find it
} else // not end of list,
{
current = current.next; // go to next link
}
}
return current; // found it
}
// -------------------------------------------------------------
public void displayList() // display the list
{
System.out.print("List (first-->last): ");
Link current = first; // start at beginning of list
while (current != null) // until end of list,
{
current.displayLink(); // print data
current = current.next; // move to next link
}
System.out.println("");
}
// -------------------------------------------------------------
public Link removeAll(int n) // delete link with given key
{ // (assumes non-empty list)
Link current = first; // search for link
Link previous = first;
while (current.iData != n) {
if (current.next == null) {
return null; // didn't find it
} else {
previous = current; // go to next link
current = current.next;
}
}
if (current == first) // if first link,
{
first = first.next; // change first
} else // otherwise,
{
previous.next = current.next; // bypass it
}
return current;
}
}
I expect to have all the values deleted for a given key but it I'm only able to delete one instance of a given value.
This removes all occurrences of Link with id == n. It should be the same if you want to remove by Link.iData.
public Link removeAll(int n)
{
Link head = first;
Link previous = null;
Link current = first;
while (current != null) {
if (current.id == n) {
if (previous == null) {
head = current.next;
} else {
previous.next = current.next;
}
} else {
previous = current; // if we removed current, let previous remain the same
}
current = current.next;
}
first = head;
return head;
}
Running the code like this:
LinkList l = new LinkList();
l.insertFirst(0, 0.1);
l.insertFirst(3, 3.1);
l.insertFirst(1, 1.1);
l.insertFirst(3, 3.1);
l.insertFirst(2, 2.1);
l.displayList();
l.removeAll(3);
l.displayList();
Outputs:
List (first-->last):
2 : 2.1
3 : 3.1
1 : 1.1
3 : 3.1
0 : 0.1
List (first-->last):
2 : 2.1
1 : 1.1
0 : 0.1
I have this class called ListNode, similar to yours.
public class ListNode {
public ListNode next;
public int val;
public ListNode removeAll(int n) {
ListNode newHead = null;
ListNode node = this;
//for keeping track of the node previous to the current node
ListNode prev = null;
//loop through the entire linked list
while (node != null) {
//when you encounter the val == n, delete the node
if (node.val == n) {
if (prev != null){
//this makes the previous node to point the node to the next of the current node
//if 2 -> 1 -> 3 and we have to remove node with key 1 and current node val == 1
// the following code will do this
// 2 -> 3
prev.next = node.next;
}
ListNode next = node.next;
//taking the same example
//this code will break the link : 1->3
node.next = null;
node = next;
} else {
if (newHead == null) {
newHead = node;
}
prev = node;
node = node.next;
}
}
return newHead;
}
}
You, basically, have to traverse through whole linked list, keeping track of the previous node for the current node and when you find a node with value/key/data equal to n, you make the previous node point to the next node of the current node and break the link of the current node to the next node.
Let's first start without deleting anything. To delete all occurrences, you first need to be able to iterate over the entire list (so you can look for multiple matches). Iterating over the whole list would simply be:
public void removeAll(int n) // delete link with given key
{
Link current = first;
Link previous = first;
while (current != null)
{
// simply move to the next Link
previous = current; // store the current node as the previous for the next iteration
current = current.next; // move to the next link
}
}
Next, let's add in a check to see if the current Link is one that should be deleted:
public void removeAll(int n) // delete link with given key
{
Link current = first;
Link previous = first;
while (current != null)
{
if (current.iData == n)
{
// To do...delete the current Link
}
else
{
// simply move to the next Link
previous = current; // store the current node as the previous for the next iteration
current = current.next; // move to the next link
}
}
}
Once we've found a match, there are two possibilities. Either the Link is the first Link, or it is somewhere further down in the list:
If the link is the first one, then we move current to the next Link, and make both first and previous point to the new current Link.
If we are not the first Link, then we move current to the next Link, and update the previous.next field to point to the new current Link (thus skipping over the Link to delete).
Here's the updated code:
public void removeAll(int n) // delete link with given key
{
Link current = first;
Link previous = first;
while (current != null)
{
if (current.iData == n)
{
if (current == first)
{
current = current.next;
first = current;
previous = current;
}
else
{
current = current.next;
previous.next = current;
}
}
else
{
// simply move to the next Link
previous = current;
current = current.next;
}
}
}
Here is simple recursive implementation (this implementation leaves initial list intact, and creates new without specified element):
public class Answer {
public static void main(String[] args) {
LinkedList list = new LinkedList(1, new LinkedList(2, new LinkedList(1, new LinkedList(2, new LinkedList(3, null)))));
System.out.println(list);
LinkedList withoutOne = list.removeAll(1);
System.out.println(withoutOne);
LinkedList withoutTwo = list.removeAll(2);
System.out.println(withoutTwo);
LinkedList withoutThree = list.removeAll(3);
System.out.println(withoutThree);
}
}
class LinkedList {
private int value;
private LinkedList next;
public LinkedList(int value, LinkedList next) {
this.value = value;
this.next = next;
}
public LinkedList removeAll(int value) {
if (this.next == null) {
return (this.value == value) ? null : new LinkedList(this.value, null);
} else if (this.value == value) {
return this.next.removeAll(value);
} else {
return new LinkedList(this.value, this.next.removeAll(value));
}
}
#Override
public String toString() {
String res = "LinkedList:";
for (LinkedList link = this; link != null; link = link.next) {
res += " " + link.value;
}
return res;
}
}
Let's say that I've a list that goes by 1->2->3->4->5. I want to put the last node after the first one so it goes like 1->5->2->3->4. This is my code but it doesn't work
public void Manipulate(){
Node curr = head;
Node next = null;
Node last = head;
while(last.next != null){
last = last.next;
}
next = curr.next;
last.next = next;
curr.next = next.next;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
SinglyLinkedList lista = new SinglyLinkedList();
int a = sc.nextInt();
int b = sc.nextInt();
lista.addFirst(a);
lista.insertAfter(a, b);
for(int i = 0; i < 2; i ++){
int c = b;
b = sc.nextInt();
lista.insertAfter(c, b);
}
lista.addLast(34);
lista.addLast(55);
lista.addLast("Ginger");
lista.Manipulate();
System.out.println(lista);
}
You already got some improvement suggestions, so here's a little explaination what you actually did wrong.
The result of your code (as is) would be:
1->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->->4->5->2->3->4->5->2->3->->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->4->5->2->3->... (going on forever)
Which is why you run out of memory when trying to print that infinite beast.
First mistake: You need to actually make sure the element that will be the new last element does no longer have your former last element as next.
Second mistake: Your head element should have the former last element as next, not the next elements of its former next element.
// Edge case: list has zero or 1 node:
if(head == null || head.next == null) {
return;
}
Node prev = null;
Node last = head;
while(last.next != null){
prev = last;
last = last.next;
}
Node tmp = head.next;
head.next = last;
last.next = tmp;
// Prevent loop by setting the next of the new last to null
prev.next = null;
public void Manipulate() {
Node penultimate = null;
Node last = head;
while(last.next != null){
penultimate = last;
last = last.next;
}
if (penultimate != null){ // closes the list
penultimate.next = null;
}
if (last != head) { // move last element to second place
last.next = head.next;
head.next = last;
}
}
Here's the method
public void sortStudentsAlphabeticallyByFirstName()
{
StudentNode unsorted = tail;
StudentNode current = header;
while(unsorted.prevNode() != null)
{
while(current != unsorted)
{
int result = (current.getFirstName()).compareToIgnoreCase(current.nextNode().getFirstName());
if(result > 0) //If in wrong order lexicographically
{
StudentNode temp = current;
StudentNode next = current.nextNode();
StudentNode previous = current.prevNode();
StudentNode nextNext = next.nextNode();
if (numberOfStudents() == 2)
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(null);
current.setPrev(null);
unsorted = temp;
}
else if(nextNext == null) //If at penultimate student therefore last comparison
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(null);
previous.setNext(current);
current.setPrev(previous);
unsorted = temp;
}
else if(previous == null) //if at beginning of student list
{
if(current.nextNode() == unsorted)
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(nextNext);
nextNext.setPrev(temp);
current.setPrev(null);
unsorted = temp; //swap unsorted back to correct position
}
else
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(nextNext);
nextNext.setPrev(temp);
current.setPrev(null);
}
}
else //else if in the middle of the list
{
if(current.nextNode() == unsorted)
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(nextNext);
nextNext.setPrev(temp);
previous.setNext(current);
current.setPrev(previous);
unsorted = temp;
}
else
{
current = current.nextNode();
current.setNext(temp);
temp.setPrev(current);
temp.setNext(nextNext);
nextNext.setPrev(temp);
previous.setNext(current);
current.setPrev(previous);
}
}
}
current = current.nextNode();
}
current = header;
unsorted = unsorted.prevNode();
}
}
Can anyone see why it cuts off the beginning of the list when I try to iterate the list again? I've used the debugger and it seems to run like it should, but I can't work out why it's doing it.
Here's the iterate list method as well if it helps
public void itterateList()
{
StudentNode u = header;
while(u != null)
{
System.out.println(u.getFirstName()+" "+u.getSurname());
u = u.nextNode();
}
}
The main problem of your code is that header and tail get never updated.
Try the following simpler code:
public void sortStudentsAlphabeticallyByFirstName()
{
StudentNode unsorted = tail;
StudentNode current = header;
while(unsorted.prevNode() != null)
{
while(current != unsorted)
{
StudentNode next = current.nextNode();
int result = (current.getFirstName()).compareToIgnoreCase(next.getFirstName());
if (result>0) // current is greater than next
{
// need to exchange : next will be before current
// HEADER (before) CURRENT NEXT (after) TAIL
// HEADER (before) NEXT CURRENT (after) TAIL
// 1 - Before current
if (current.prevNode() != null)
current.prevNode().setNext(next);
else header = next;
// 2 - After next
if (next.nextNode() != null)
next.nextNode().setPrev(current);
else tail = current;
// 3 - current <-> next
current.setNext(next.nextNode());
next.setPrev(current.prevNode());
current.setPrev(next);
next.setNext(current);
// Don't need to update current which is
// already pointing to the greatest element
}
// next is greater than current -> update current
else current = current.nextNode();
}
current = header;
unsorted = unsorted.prevNode();
}
}
How I can convert this doubly linked list into a doubly linked circular list?
public class DoublyLinkedList {
private Link first;
private Link last;
public DoublyLinkedList() {
first = null;
last = null;
}
public boolean isEmpty(){
return first == null;
}
public void insertFirst(long dd){
Link newLink = new Link(dd);
if (isEmpty())
last = newLink;
else
first.previous = newLink;
newLink.next = first;
first = newLink;
}
public void insertLast(long dd){
Link newLink = new Link(dd);
if (isEmpty())
first = newLink;
else {
last.next = newLink;
newLink.previous = last;
}
last = newLink;
}
public Link deleteFirst(){
Link temp = first;
if (first.next == null)
last = null;
else
first.next.previous = null;
first = first.next;
return temp;
}
public Link deleteLast(){
Link temp = last;
if (first.next == null)
first = null;
else
last.previous.next = null;
last = last.previous;
return temp;
}
public boolean insertAfter(long key, long dd) {
Link current = first;
while (current.dData != key){
current = current.next;
if (current == null)
return false; // cannot find it
}
Link newLink = new Link(dd); // make new link
if (current == last) // if last link,
{
newLink.next = null;
last = newLink;
} else // not last link,
{
newLink.next = current.next;
current.next.previous = newLink;
}
newLink.previous = current;
current.next = newLink;
return true; // found it, insert
}
public Link deleteKey(long key){
Link current = first;
while (current.dData != key)
{
current = current.next;
if (current == null)
return null; // cannot find it
}
if (current == first) // found it; first item?
first = current.next;
else
current.previous.next = current.next;
if (current == last) // last item?
last = current.previous;
else
// not last
current.next.previous = current.previous;
return current; // return value
}
public void displayForward() {
System.out.print("List (first to last): ");
Link current = first; // start at beginning
while (current != null) // until end of list,
{
current.displayLink();
current = current.next; // move to next link
}
System.out.println("");
}
public void displayBackward() {
System.out.print("List : ");
Link current = last;
while (current != null){
current.displayLink();
current = current.previous;
}
System.out.println("");
}
public static void main(String[] args) {
DoublyLinkedList theList = new DoublyLinkedList();
theList.insertFirst(22);
theList.insertFirst(44);
theList.insertLast(33);
theList.insertLast(55);
theList.displayForward();
theList.displayBackward();
theList.deleteFirst();
theList.deleteLast();
theList.deleteKey(11);
theList.displayForward();
theList.insertAfter(22, 77); // insert 77 after 22
theList.insertAfter(33, 88); // insert 88 after 33
theList.displayForward();
}
}
class Link {
public long dData; // data item
public Link next; // next link in list
public Link previous; // previous link in list
public Link(long d)
{
dData = d;
}
public void displayLink(){
System.out.print(dData + " ");
}
}
Thanks
The list, as is, doesn't provide a way to iterate over its elements. If it did, you could ask the list for an iterator and get the next element of the list from the iterator, until it reaches the last element. Making it circular would change the iterator behavior: it would go back to the first element once the last element is reached.
So, the answer is that to make it circular, you have to change the methods of the list so that the next link of the last one is the first one, an the previous link of the first one is the last one. But if you don't add other methods to the list, doing it won't change anything: the public behavior of the existing methods will stay the same once the list is made circular.