C语言的单链表逆序和指定范围逆序
生活随笔
收集整理的這篇文章主要介紹了
C语言的单链表逆序和指定范围逆序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 逆序
- 指定范圍逆序
- 源碼實現
前言
關于鏈表的逆置,是考察對鏈表指針的理解。知道了如何不實用額外空間,同時使用O(n)復雜度對鏈表進行逆序之后將會對鏈表有好理解。
同時關于如何在指定范圍內對鏈表逆置同樣可以進一步加深理解
逆序
基本過程如下:
- 保留原始鏈表的next指針域,p = head -> next
- 將原始鏈表的next指針域指向新鏈表的頭部,head -> next = new_head
- 新鏈表指針向前移動一位,new_head = head
- 原始鏈表頭指針向后移動一位,指向之前保留的原始指針的next域,head = p
···
以上過程實現如下:
Data *reverse(Data *head) {Data *new_head = NULL;while(head) {Data *p = head -> next;head -> next = new_head;new_head = head;head = p;}return new_head;
}
指定范圍逆序
基本過程如下,指定鏈表的第2-4個節點進行逆序,其他節點保持原有順序
這個過程需要關注如下幾個關鍵節點
- 逆序前的頭節點和逆序后的尾節點需要確認,確認之后在此范圍即可進行如上過程的鏈表逆序
- 逆序完成之后需要連接頭節點
- 逆序完成之后需要連接尾節點
實現過程如下:
/*指定范圍,逆序m-n之間的節點*/
Data *reverse_betweenM_N(Data *head, int m, int n) {Data *result, new_tail;Data *new_head = NULL;Data *pre_head = NULL;/*計算需要逆序的節點個數,從而能夠找到逆序的尾節點*/int change = n - m + 1;/*跳過m個節點,找到逆序前的第一個節點*/result = head;while(head && --m) {pre_head = head;head = head -> next;}/*保留逆序前的第一個節點,逆序后將變為尾節點*/Data *list_tail = head;/*逆序m-n之間的節點*/while(head && change) {Data *p = head -> next;head -> next = new_head;new_head = head;head = p;change --;}/*逆序完成之后,將逆序后的尾節點指向鏈表結尾*/list_tail -> next = head;/*確認逆序節點不是從鏈表頭節點開始:如果是則最終頭節點為逆序后的頭節點否則將頭節點指向逆序后的頭節點,保持鏈表完成性*/if (pre_head) {pre_head -> next = new_head;result = pre_head;} else {result = new_head;}return result;
}
源碼實現
#include <stdio.h>
#include <stdlib.h>/*鏈表數據域和指針域*/
typedef struct link_list {int data;struct link_list *next;
}Data;/*打印鏈表*/
void print_list(Data *head) {while (head) {printf("%d ",head->data);head = head -> next;}printf("\n");
}/*頭插法創建鏈表*/
Data *insert_head(Data *head, int n) {head = (Data *)malloc (sizeof(Data));head -> next = NULL;int data;while(n --) {Data *p = (Data *)malloc(sizeof(Data));scanf("%d",&data);p -> data = data;p -> next = head -> next;head -> next = p;}return head;
}/*尾插法創建鏈表*/
Data *insert_tail(Data *head, int n) {head = (Data *)malloc(sizeof(Data));head -> next = NULL;Data *r = head;int data;while(n--) {Data *p = (Data *)malloc(sizeof(Data));scanf("%d", &data);p -> data = data;r -> next = p;r = p;p -> next = NULL;}return head;
}/*鏈表逆序*/
Data *reverse(Data *head) {Data *new_head = NULL;while(head) {Data *p = head -> next;head -> next = new_head;new_head = head;head = p;}return new_head;
}/*鏈表指定范圍逆序*/
Data *reverse_betweenM_N(Data *head, int m, int n) {Data *result, new_tail;Data *new_head = NULL;Data *pre_head = NULL;int change = n - m + 1;result = head;while(head && --m) {pre_head = head;head = head -> next;}Data *list_tail = head;while(head && change) {Data *p = head -> next;head -> next = new_head;new_head = head;head = p;change --;}list_tail -> next = head;if (pre_head) {pre_head -> next = new_head;result = pre_head;} else {result = new_head;}return result;
}int main() {Data *head;printf("construct link list :\n");head = insert_tail(head,5);Data *test = reverse_betweenM_N(head -> next,2,4);printf("after reverse between 2-4:\n");print_list(test);Data *rever = reverse(head -> next);printf("after reverse :\n");print_list(rever);return 0;
}
輸出如下:
construct link list :
1 2 3 4 5
after reverse between 2-4:
1 4 3 2 5
after reverse :
5 2 3 4 1
總結
以上是生活随笔為你收集整理的C语言的单链表逆序和指定范围逆序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台式电脑一般要多少钱?
- 下一篇: C语言的单链表创建:头插法/尾插法