一:什么是鏈表的逆序
? ? ? ? (1)鏈表的逆序又叫反向,意思就是把鏈表中所有的有效節點在鏈表中的順序給反過來
二:單鏈表逆序算法分析
? ? ? ? (1)當需要對一個數據結構進行操作時,就有必要有一套算法。這就是數據結構和算法的關系
? ? ? ? (2)算法的兩個層次:第一個層次是數學和邏輯上的算法;第二個層次是編程語言來實現算法
? ? ? ? (3)從邏輯上來講,鏈表的逆序有很多種方法。這些方法最終都能實現需要,但是效率是一樣的。彼此的可擴展性容錯性等不同
? ? ? ? (4)思路:首先先遍歷節點,然后將原鏈表中的頭指針頭節點作為新鏈表的頭指針頭節點,再將原鏈表中的有效節點挨個依次取出來,采用頭部插入的方法插入進新鏈表
? ? ? ? (5)鏈表逆序 = 遍歷 + 頭插入
三:逆序代碼實現
? ? ? ?(1)實現函數
/****************************************
函數名:reverse
作用:將鏈表進行反向排序
返回值:無
參數:ph 鏈表頭指針
****************************************/
void reverse(struct node *ph)
{strucct node *p = ph->pNEXT;STRUCT NODE *pback = ph;if((p == NULL) || (p->pNEXT == NULL)) //判斷是否是只有一個節點還是沒有有效節點{return; //當鏈表中只有一個節點或沒有有效節點時不需要操作}//當鏈表有兩個或兩個以上的節點才需要進行操作while(NULL != p->pNEXT) //判斷是不是最后一個節點{back = p->pNEXT; //保存p節點后的一個節點if(p == ph->pNEXT){//原鏈表的第一個有效節點,在逆序之后會變成尾節點,將這個節點的//指針指向NULLp->pNEXT = NULL;}else{//不是原鏈表的第一個有效節點,指向上一個頭節點指向的節點地址p->pNEXT = ph->pNEXT; }ph->pNEXT = p; //頭節點指向新插入的節點p = pback; //將下一個要插入的節點的地址給指針臨時變量}//在進行遍歷時判斷條件是不是最后一個節點,這樣會丟失最后一個節點insert_head(ph,p->pNEXT);}
(2)程序源碼
#include <stdio.h>
#include <string.h>
#include <stdlib.h>struct node
{int datas;struct node *pNEXT;};struct node *create(int a)
{struct node *p = (struct node *)malloc(sizeof(struct node));if(NULL == p){printf("malloc error!\n");return NULL;}memset(p,0,sizeof(struct node)); //bzero(p,sizeof(struct node));p->datas = a;p->pNEXT = NULL;return p;}void insert_tail(struct node *phead,struct node *new)
{struct node *p = phead;int cat = 0;while(NULL != p->pNEXT){p = p->pNEXT;cat++;}p->pNEXT = new;phead->datas = cat +1;}void insert_head(struct node *head,struct node *new)
{new->pNEXT = head->pNEXT;head->pNEXT = new;head->datas += 1;}void ergodic(struct node *ph)
{struct node *p = ph;int cat = 0;printf("datas number is a: %d\n",p->datas);while(NULL != p->pNEXT){cat++;printf("datas number is :%d\n",cat); p = p->pNEXT; printf("datas is: %d\n",p->datas); }}int delete(struct node *ph,int data)
{struct node *p = ph;struct node *prev = NULL;int cat = 0;while(NULL != p->pNEXT){prev = p;p = p->pNEXT; if(p->datas == data){if(NULL == p->pNEXT){ prev->pNEXT = NULL;free(p);cat = ph->datas;ph->datas = cat -1;}else{prev->pNEXT = p->pNEXT;free(p);cat = ph->datas;ph->datas = cat -1;} return 0;} }return -1;}void reverse(struct node *ph)
{strucct node *p = ph->pNEXT;STRUCT NODE *pback = ph;if((p == NULL) || (p->pNEXT == NULL)) //判斷是否是只有一個節點還是沒有有效節點{return; //當鏈表中只有一個節點或沒有有效節點時不需要操作}//當鏈表有兩個或兩個以上的節點才需要進行操作while(NULL != p->pNEXT) //判斷是不是最后一個節點{back = p->pNEXT; //保存p節點后的一個節點if(p == ph->pNEXT){//原鏈表的第一個有效節點,在逆序之后會變成尾節點,將這個節點的//指針指向NULLp->pNEXT = NULL;}else{//不是原鏈表的第一個有效節點,指向上一個頭節點指向的節點地址p->pNEXT = ph->pNEXT; }ph->pNEXT = p; //頭節點指向新插入的節點p = pback; //將下一個要插入的節點的地址給指針臨時變量}//在進行遍歷時判斷條件是不是最后一個節點,這樣會丟失最后一個節點insert_head(ph,p);}int main(void)
{struct node *phead = create(0);insert_tail(phead,create(12)); insert_tail(phead,create(13));insert_tail(phead,create(14));ergodic(phead); //遍歷打印各個節點數據區reverse(phead); //將鏈表進行逆序ergodic(phead); //再次遍歷打印各個節點數據區return 0;}
運行結果:
?