单链表总结

来源:互联网 发布:华为手机数据迁移sd卡 编辑:程序博客网 时间:2024/06/05 08:52


个人总结,以及借鉴他人代码,有些代码来自平时积累,不记得出处,请见谅。

欢迎各位转载,希望对大家有用!如有错误欢迎指正,谢谢!

struct node {int val;node *next;};//链表翻转static void Reverse(struct node* headRef) {struct node* result = NULL;//首节点为空struct node* current = headRef;struct node* next;while (current != NULL) {next = current->next; // tricky: note the next node--》先得到下一个节点current->next = result; // move the node onto the result》指向上一节点result = current;current = next;}headRef = result;}//递归翻转//利用递归的性质,先遍历,最后倒序改变!void RecursiveReverse(struct node* headRef) {struct node* first;struct node* rest;if (headRef == NULL) return; // empty list base casefirst = headRef; // suppose first = {1, 2, 3}rest = first->next; //         rest = {2, 3}if (rest == NULL) return; // empty rest base caseRecursiveReverse(&rest); // Recursively reverse the smaller {2, 3} case// after: rest = {3, 2}first->next->next = first; // put the first elem on the end of the listfirst->next = NULL; // (tricky step -- make a drawing)//末尾加入NULLheadRef = rest; // fix the head pointer//传递给头节点,每个都是关乎自身}//求长度int Length(struct node* head) {int count = 0;struct node* current = head;while (current != NULL) {count++;current=current->next;}return(count);}//加入节点在头前void Push(struct node* headRef, int newData) {struct node* newNode =(struct node*) malloc(sizeof(struct node)); // allocate nodenewNode->data = newData; // put in the datanewNode->next = (headRef); // link the old list off the new node(headRef) = newNode; // move the head to point to the new node}struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};//合并俩个链表并排序ListNode *sort_merge(ListNode *first_lk,ListNode *second_lk) {   ListNode head_temp(0);  ListNode* temp_head = &head_temp;   ListNode *save_head=temp_head;  ListNode* head ;  while(first_lk!=NULL&&second_lk!=NULL)  {  if(first_lk->val<second_lk->val)  {  temp_head->next=first_lk;  first_lk=first_lk->next;  }  else  {  temp_head->next=second_lk;  second_lk=second_lk->next;     }  temp_head=temp_head->next;  }  if(first_lk != NULL)  temp_head->next=first_lk;  else  temp_head->next=second_lk;  head=save_head->next;  return head;  }  //获取链表的中间位置    --》通过快慢俩指针,一个一次走一步snow,一个一次走俩步fast// len/2 下整ListNode *get_midpos(ListNode *head,ListNode *end) {  ListNode *mid_pos,*pre_pos;  ListNode *end_pos;  //if(head == NULL||head->next==NULL)return head;  mid_pos=head;  end_pos=head;  while(end_pos != end&&end_pos->next != end)  {  pre_pos=mid_pos;  //用于去下整mid_pos=mid_pos->next;  end_pos=end_pos->next->next;  }  return pre_pos;  }  //基于以上函数,进行归并排序实现时间复杂度为O(nlgn)的链表排序!ListNode * merge_sort(ListNode *head) {   ListNode *mid_pos,*mid_next_llk;  ListNode *sort_list_1,*sort_list_2;  if(head == NULL||head->next==NULL)return head;//为空或者为单独一个节点  mid_pos=get_midpos(head,NULL);  mid_next_llk=mid_pos->next;//第二个链表位置  mid_pos->next=NULL;//拆分成俩个链表   sort_list_1=merge_sort(head);  sort_list_2=merge_sort(mid_next_llk);  //注意这个对链表操作是有修改的!特别是头指针位置!return   merge(sort_list_1,sort_list_2);//合并  }  //详细见:http://blog.csdn.net/jiangxi756/article/details/16839901//从中间撕裂链表void spilt_mid(ListNode *src,ListNode *first,ListNode *second){ListNode *mid_pos=get_midpos(src,NULL);second=mid_pos->next;//链表2mid_pos=NULL;first=src;//链表1}//删除有序列表的重复串// Remove duplicates from a sorted listvoid RemoveDuplicates(struct node* head) {struct node* current = head;26if (current == NULL) return; // do nothing if the list is empty// Compare current node with next nodewhile(current->next!=NULL) {if (current->data == current->next->data) {struct node* nextNext = current->next->next;free(current->next);current->next = nextNext;}else {current = current->next; // only advance if no deletion}}}//添加节点到尾部void Append(struct node* aRef, struct node* bRef) {struct node* current;if (aRef == NULL) { // Special case if a is emptyaRef = bRef;}else { // Otherwise, find the end of a, and append b therecurrent = aRef;while (current->next != NULL) { // find the last nodecurrent = current->next;}24current->next = bRef; // hang the b list off the last node}bRef=NULL; // NULL the original b, since it has been appended above}//插入排序//以下用于有序链表插入一个元素// Uses special case code for the head endvoid SortedInsert(struct node* headRef, struct node* newNode) {// Special case for the head endif (headRef == NULL || (headRef)->data >= newNode->data) //比头结点大{newNode->next = headRef;headRef = newNode;}else {// Locate the node before the point of insertion-->定位节点插入位置struct node* current = headRef;while (current->next!=NULL && current->next->data<newNode->data) {current = current->next;}newNode->next = current->next;current->next = newNode;//以上俩句用于插入!}}void InsertSort(struct node* headRef) {struct node* result = NULL; // build the answer herestruct node* current = headRef; // iterate over the original liststruct node* next;while (current!=NULL) {next = current->next; // tricky - note the next pointer before we change itSortedInsert(result, current);current = next;}headRef = result;}//pop实现int Pop(struct node* headRef) {struct node* head;int result;head = headRef;assert(head != NULL);result = head->data; // pull out the data before the node is deletedheadRef = head->next; // unlink the head node for the caller// Note the * -- uses a reference-pointer//  just like Push() and DeleteList().free(head); // free the head nodereturn(result); // don't forget to return the data from the link}//删除链表-》用临时指针暂存,再删!void DeleteList(struct node* headRef) {struct node* current = headRef; // deref headRef to get the real headstruct node* next;while (current != NULL) {next = current->next; // note the next pointerfree(current); // delete the nodecurrent = next; // advance to the next node}headRef = NULL; // Again, deref headRef to affect the real head back// in the caller.}//从下标为0,开始,逐个比较判断int GetNth(struct node* head, int index) {struct node* current = head;int count = 0; // the index of the node we're currently looking atwhile (current != NULL) {if (count == index) return(current->data);count++;current = current->next;}assert(0); // if we get to this line, the caller was asking// for a non-existent element so we assert fail.}//给单链表建环---找到指定交点,在调整指针bool build_loop_list(node *head ,int index)//从0开始下标{int count = 0;int *ptemp_node_start,*ptemp_node_end;while(count<index){if(head==NULL)return false;head=head->next;count++;}ptemp_node_start = head;while(head->next!=NULL)//求环末尾节点{head=head->next;}ptemp_node_end = head;ptemp_node_end->next=ptemp_node_start;return true;}//检测单链表是否有环bool detect_looplink(node *head)  {  node *quick_node = head->next, *slow_node = head;  if(head == NULL || head->next == NULL)  {  return false;  }  while(quick_node != slow_node)  {  if(quick_node == NULL || slow_node == NULL)  break;  quick_node = quick_node->next->next;  slow_node = slow_node->next;  }  if(quick_node != NULL && slow_node != NULL)    //非尾节点相遇   return true; return false;  }  //检测两条链表是否相交,并找到相应交点--//思路:把2个链表各遍历一遍,记下长度length1和length2,若2者的尾节点指针相等,则相交。   // 之后再把长的链表从abs(len1-len2)的位置开始遍历,第一个相等的指针为目标节点node* detect_intersect_links(node *first_link, node *second_link)  {  int legnth1 = 1, length2 = 1, pos = 0;  node *cur = NULL, *longer_link = first_link, *shorter_link = second_link;  if(first_link == NULL || second_link == NULL)  {  return NULL;  }  while(first_link->next || second_link->next)     //遍历2个链表   {  if(first_link->next)  {  first_link = first_link->next;  ++legnth1;  }  if(second_link->next)  {  second_link = second_link->next;  ++length2;  }  }  if(first_link != second_link)                 //比较尾节点   {  return NULL;  }  pos = legnth1 - length2;  if(legnth1 < length2)                  //保证 longer_link为长链表   {  pos = length2 - legnth1;  cur = longer_link;  longer_link = shorter_link;  shorter_link = cur;  }  while(pos-- > 0)  longer_link = longer_link->next;//长链表先定位到多余长度的下一个节点  while(longer_link || shorter_link)  {  if(longer_link == shorter_link)                  //找到第一个交点   {  return longer_link;  }  longer_link = longer_link->next;  shorter_link = shorter_link->next;  }  return NULL;  }  




原创粉丝点击