数据结构-C语言单链表逆序

生命不息,奋斗不止。又到双十一,别人都在扫货,程序员还在改BUG~~~~~

先贴上别人讲解的链接:单链表逆序

直接上程序,链表没有注释,只有在逆序的函数加了一下自己的理解。

list.h

 

/*************************************************************************
	> File Name: list.h
	> Author: bairutai
	> Mail: bairutai@aliyun.com 
	> Created Time: 2015年11月10日 星期二 19时09分17秒
 ************************************************************************/
#ifndef LIST_H
#define LIST_H
#include<stdbool.h>
typedef int T;
typedef struct Node *PNode;
typedef struct Node {
	T data;
	PNode next;
}List;

PNode initList();
void destoryList(PNode*);
void insert(PNode head,PNode p,PNode s);
PNode makenode(T i);
PNode Reverse(PNode);
PNode Reverse2(PNode);
bool isEmpty(PNode);
#endif


list.c

 

 

/*************************************************************************
	> File Name: list.c
	> Author: bairutai
	> Mail: bairutai@aliyun.com 
	> Created Time: 2015年11月10日 星期二 19时40分24秒
 ************************************************************************/

#include<stdio.h>
#include"list.h"
#include<malloc.h>
#include<stdlib.h>
PNode initList()
{
	PNode node = (PNode)malloc(sizeof(List));
	node->next = NULL;
	return node;
}

void destoryList(PNode* list)
{
	if(NULL == *list){
		return;
	}
	PNode node = *list;
	PNode tmp = NULL;
	while(NULL != node)
	{
		tmp = node;
		node->next = NULL;
		free(node);
		node = tmp->next;
	}
	*list = NULL;
}

bool isEmpty(PNode list)
{
	if(NULL == list){
		return true;
	}
	else {
		return false;
	}
}

void insert(PNode head,PNode p,PNode s)
{
	if(NULL == head){
		return;
	}
	if(p == head){
		s->next = head->next;
		head->next = s;
	//	head->data = s->data;
	}
	else{
		s->next = p->next;
		p->next = s;
	}
}

PNode makenode(T i)
{
	PNode p = (PNode)malloc(sizeof(List));
	p->data = i;
	p->next = NULL;
	return p;
}

//非递归方式 
//第一次,cur结点为空,next结点记录第二个结点,头结点断开,cur结点移到头结点的位置,头结点移到第二个结点位置
//第二次,cur结点为头结点,next结点记录第三个结点,第二个结点的next指针与头结点连接,
//        cur结点移动到第二个结点位置,头结点移动到第三个结点位置
//然后重复
PNode Reverse(PNode list)
{
	PNode next = NULL;
	PNode cur = NULL;
	while(NULL != list)
	{
		next = list->next;
		list->next = cur;
		cur = list;
		list = next;
	}
	return cur;
}

//递归方式
//先递归找到最后一个结点,如果next指针为空,则是最后一个结点,返回新的头结点
//倒数第二次递归,将最后一个结点的next指针指向倒数第二个结点,并将倒数第二个结点的next指针断开(会在倒数第三次递归的时候指向倒数第三个结点).
PNode Reverse2(PNode list)
{
	PNode newhead = NULL;
	if(NULL == list || NULL == list->next){
		return list;
	}
	newhead = Reverse2(list->next);
	list->next->next = list;
	list->next =  NULL;
	return newhead;
}


test.c

 

 

/*************************************************************************
	> File Name: test.c
	> Author: bairutai
	> Mail: bairutai@aliyun.com 
	> Created Time: 2015年11月10日 星期二 20时20分37秒
 ************************************************************************/

#include<stdio.h>
#include"list.h"
main()
{
	PNode list = initList();
	PNode p1 = makenode(1);
	PNode p2 = makenode(2);
	PNode p3 = makenode(3);
	PNode p4 = makenode(4);
	insert(list,list,p1);
	insert(list,p1,p2);
	insert(list,p2,p3);
	insert(list,p3,p4);
	PNode p = list;
	while(NULL != p){
		printf("data is %d\n",p->data);
		p = p->next;
	}

	PNode list2 = Reverse(list);
	PNode p_ = list2;
	while(NULL != p_){
		printf("data2 is %d\n",p_->data);
		p_ = p_->next;
	}
	PNode list3 = Reverse2(list2);
	PNode p__ = list3;
	while(NULL != p__){
		printf("data3 is %d\n",p__->data);
		p__ = p__->next;
	}
	destoryList(&list3);
	if(isEmpty(list3)){
		printf("list3 是个空链表\n");		
	}
	else {
		printf("list3 不是个空链表\n");		
	}
}


结果

 

 

data is 0
data is 1
data is 2
data is 3
data is 4
data2 is 4
data2 is 3
data2 is 2
data2 is 1
data2 is 0
data3 is 0
data3 is 1
data3 is 2
data3 is 3
data3 is 4
list3 是个空链表


makefile

 

 

OBJECT	=list.o test.o
CC		=gcc
CFLAG	=-c

test:$(OBJECT)
	$(CC) -o $@ $(OBJECT)
test.o:test.c list.c list.h 
	$(CC) $(CFLAG) -o $@ $<
list.o:list.c list.h 
	$(CC) $(CFLAG) -o $@ $<
clean:
	rm $(OBJECT) -rf

 

 

 

单链表的就地逆置是指不引入新的节点,只调整原有节点的指针,将单链表逆序排列。 实现单链表的就地逆置可以使用三个指针:prev、curr和next。开始时,将prev指向NULL,curr指向链表的首节点,next指向curr的下一个节点。 接下来,通过循环遍历单链表,每次将curr的指针指向prev,然后将prev、curr和next指针都向后移动一个节点。直到curr指向NULL,表示已经遍历到链表的末尾。 最后,将链表的头节点指向prev,完成就地逆置。 以下是C语言实现的代码示例: #include <stdio.h> struct Node { int data; struct Node* next; }; // 单链表就地逆置函数 void reverseList(struct Node** head){ struct Node* prev = NULL; struct Node* curr = *head; struct Node* next = NULL; while(curr != NULL){ next = curr->next; curr->next = prev; prev = curr; curr = next; } *head = prev; } // 打印单链表函数 void printList(struct Node* head){ struct Node* temp = head; while(temp != NULL){ printf("%d ", temp->data); temp = temp->next; } printf("\n"); } int main(){ // 创建一个示例单链表: 1 -> 2 -> 3 -> 4 -> 5 struct Node* head = NULL; struct Node* second = NULL; struct Node* third = NULL; struct Node* fourth = NULL; struct Node* fifth = NULL; head = (struct Node*)malloc(sizeof(struct Node)); second = (struct Node*)malloc(sizeof(struct Node)); third = (struct Node*)malloc(sizeof(struct Node)); fourth = (struct Node*)malloc(sizeof(struct Node)); fifth = (struct Node*)malloc(sizeof(struct Node)); head->data = 1; head->next = second; second->data = 2; second->next = third; third->data = 3; third->next = fourth; fourth->data = 4; fourth->next = fifth; fifth->data = 5; fifth->next = NULL; printf("原始链表: "); printList(head); reverseList(&head); printf("就地逆置后的链表: "); printList(head); return 0; } 运行此程序,输出结果为: 原始链表: 1 2 3 4 5 就地逆置后的链表: 5 4 3 2 1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值