个人总结,以及借鉴他人代码,有些代码来自平时积累,不记得出处,请见谅。
欢迎各位转载,希望对大家有用!如有错误欢迎指正,谢谢!
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 case
first = headRef; // suppose first = {1, 2, 3}
rest = first->next; // rest = {2, 3}
if (rest == NULL) return; // empty rest base case
RecursiveReverse(&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 list
first->next = NULL; // (tricky step -- make a drawing)//末尾加入NULL
headRef = 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 node
newNode->data = newData; // put in the data
newNode->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;//链表2
mid_pos=NULL;
first=src;//链表1
}
//删除有序列表的重复串
// Remove duplicates from a sorted list
void RemoveDuplicates(struct node* head) {
struct node* current = head;26
if (current == NULL) return; // do nothing if the list is empty
// Compare current node with next node
while(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 empty
aRef = bRef;
}
else { // Otherwise, find the end of a, and append b there
current = aRef;
while (current->next != NULL) { // find the last node
current = current->next;
}24
current->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 end
void SortedInsert(struct node* headRef, struct node* newNode)
{
// Special case for the head end
if (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 here
struct node* current = headRef; // iterate over the original list
struct node* next;
while (current!=NULL) {
next = current->next; // tricky - note the next pointer before we change it
SortedInsert(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 deleted
headRef = 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 node
return(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 head
struct node* next;
while (current != NULL) {
next = current->next; // note the next pointer
free(current); // delete the node
current = 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 at
while (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;
}