200 likes | 277 Views
Summary on linked lists. Definition:. struct Node{ int data; Node* next; }; typedef Node* NodePtr; NodePtr head;. Head. 20. 45. 75. 85. Operations on (unsorted) linked lists. bool listEmpty(NodePtr head) { return (head==NULL); } int getHead(NodePtr head) {
E N D
Summary on linked lists Definition: struct Node{ int data; Node* next; }; typedef Node* NodePtr; NodePtr head; Head 20 45 75 85
Operations on (unsorted) linked lists bool listEmpty(NodePtr head) { return (head==NULL); } int getHead(NodePtr head) { if (head != NULL) return head->data; else {cout << “Error” << endl; exit(1);}; } NodePtr getRest(NodePtr head) { NodePtr p=NULL; if (head != NULL) p=head->next; return p; } NodePtr addHead(NodePtr head, int newdata) { // or: void addHead(NodePtr& head, int newdata) { NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = head; return newPtr; // or: head = newPtr; } NodePtr delHead(NodePtr Head){ // or: void delHead(NodePtr& head) if(head != NULL){ NodePtr cur = head; head = head->next; delete cur; } return head; // no return for ‘void delHead()’ } (! listEmpty())
Operations on sorted linked lists: bool listEmpty(NodePtr head) { ... } NodePtr insertNode(NodePtr head, int item) { // or: void insertNode(NodePtr& head, int item){ ... } NodePtr deleteNode(NodePtr head, int item) { // or: void deleteNode(NodePtr& head, int item){ ... } (finding the right position should be careful in implementation!)
NodePtr insertNode(NodePtr head, int item){ NodePtr newp, cur, pre; newp = new Node; newp->data = item; pre = NULL; cur = head; while( (cur != NULL) && (item>cur->data)){ pre = cur; cur = cur->next; } if(pre == NULL){ //insert to head of linked list newp->next = head; head = newp; } else { pre->next = newp; new->next = cur; } return head; } If the position happens to be the head General case
NodePtr deleteNode(NodePtr head, int item){ NodePtr prev=NULL, cur = head; while( (cur!=NULL) && (item > cur->data)){ prev = cur; cur = cur->next; } if ( cur!==NULL && cur->data==item) { if(cur==Head) Head = Head->next; else prev->next = cur->next; delete cur; } return head; }
Some simple algorithms • Write a function that returns the length of a given list. • Write a boolean function that tests whether a given unsorted list of characters is a palindrome. • Write a function that computes the union of two sorted linked lists of integers.
The length of a given list: int length(NodePtr head) { NodePtr cur = head; int l=0; while(cur != NULL){ l++; cur = cur->next; } return l; }
Recursive version: int length(NodePtr head) { int l; if(head==NULL) l=0; else l=length(head->next)+1; return l; } Or in functions: int length(NodePtr head) { int l; if(listEmpty(head)) l=0; else l=length(getRest(head))+1; return l; } deleteHead
Everything is recursive with lists: recursively print a list: void print(NodePtr head) { if(head != NULL){ cout << head->data; print(head->next); } }
Test if the given list is a palindrome: [a b c d d c b a] is a palindrome, [a b c d c] is not. bool isPalindrome(NodePtr head) { 1. create a new list in inverse order, newList 2. check the two lists, head and newList, whether they are the same }
Create a new list in the inverse order newHead is the pointer to the new list! NodePtr newHead=NULL; NodePtr p=Head; while(p != NULL) { addHead(newHead,p->data); // or: newHead=addHead(newHead,p->data); p=p->next; }
Check wheter two lists are the same: NodePtr p1 = head; NodePtr p2 = newList; bool palindrome=true; while((p1 != NULL) && (palindrome) ){ if ((p1->data)==(p2->data)) { p1=p1->next; p2=p2->next; } else palindrome=false; } return palindrome;
Create the new list bool isPalindrome(NodePtr head) { NodePtr newList=NULL; NodePtr p=head; while(p != NULL) { addHead(newList,p->data); p=p->next; } NodePtr p1=head; NodePtr p2=newList; bool palindrome=true; while((p1 != NULL) && (palindrome) ){ if ((p1->data)==(p2->data)) { p1=p1->next; p2=p2->next; } else palindrome=false; } p=newList; while (p!=NULL) { delHead(p); } return palindrome; } Test the two lists Remove the newList properly!
Do it recursively To do this, we need to use the functional definition of addEnd: NodePtr addEnd(NodePtr Head, int item) bool isPalindrome(NodePtr head) { bool palin; NodePtr newHead=reverse(head); palin=equal(head, newHead); deleteList(newHead); return palin; }
NodePtr reverse(NodePtr head) { NodePtr res; if (head==NULL) res=NULL; else res=addEnd(reverse(head->next),head->data); return res; }
bool equal(NodePtr p1, NodePtr p2) { bool equality; if (p1==NULL) equality = true; else if ((p1->data)!=(p2->data)) equality = false; else equality=palindrome(p1->next,p2->next); return equality; }
void deleteList(NodePtr head) { NodePtr p=head; if (p!=NULL) { p=deleteHead(p); deleteList(p); } }
Union of two sorted lists: given two sorted linked lists, create a new sorted list that is the union of the two. union ([1, 2, 4, 5], [3, 4, 5, 6, 7]) gives [1, 2, 3, 4, 5, 6, 7]
NodePtr union(NodePtr p1, NodePtr p2) { // look at the frist list p1 while (p1 is not empty) { just copy it! } // simply: unionList = p1; // start from p1 // look at the second list p2 while(p2 is not empty){ if the first element of p2 is not in the current union, then add it into the union list otherwise, move forward the list } return unionL; }
NodePtr union(NodePtr p1, NodePtr p2) { NodePtr unionL, p; if (p1==NULL) unionL=p2; else if (p2==NULL) unionL=p1; else { unionL=p1; p=p2; while((p != NULL) ){ if (!searchNode(unionL, p->data)) insertNode(unionL,p->data); p=p->next; } } return unionL; }