链表实现
链表每一个节点包含数据域和指针域,第一个节点数据域为NULL,指针域指向下一个节点数据域。
//定义一个链表结构
//用typedef为struct数据类型取名为list
//Node是定义结构体时的标签,与struct是一个整体
typedef struct Node
{
int date; //链表一个节点的数据域
struct Node *next; //定义一个指向结构体类型的指针
}list; //同时也表示结构体变量
typedef struct Node *a;//定义结构体指针变量
list *a;
访问节点数据域:p->data
节点指针域指针:p->next,指向下一个节点
//初始化一个链表
list *create(int n)
{
list *head,*node,*end; //定义头节点、普通节点、尾节点,每个节点都是一个结构体类型
head = (list*)malloc(sizeof(list));//malloc是动态内存分配函数,如果分配成功则返回指向被分配内存的结构体类型指针
end=head; //若是空链表,则头尾节点一样(空链表),给end一个初始化指向,形成空链表
for(int i = 0;i < n; i++){
node = (list*)malloc(sizeof(list)); //分配内存
scanf("%d",&node->data);
end->next = node;//下一个地址就是node地址(end->next 表示指向下一个地址)
end = node;//end指针指向node里面的内容(数据域与指针域),清空node
//end在前面还没有给他分配地址空间,让end指向node地址,node再次去获取。
}
end->next = NULL; //结束创建
return head;
}
关于malloc函数的用法
C语言中,malloc是动态内存分配函数。
函数原型:void malloc(unsigned int num_bytes);
参数:num_bytes 是无符号整型,用于表示分配的字节数。
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者…)
功能:分配长度为num_bytes字节的内存块
注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。
- 问题描述
已知1个List: 1->2->3->4->5;
要求把List反转变为:5->4->3->2->1。
- 问题分析
问题很简单,新创建一个list:
(1)从List中取首元素l;
(2)把这个元素l,按照前插法插入到list中
(3)重复(1)(2),直到List中没有元素 - 算法实现
//方法三从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
typedef struct list{
int data;
struct list* next;
}List;
List* ReverseList(List *list) //定义一个结构体类型的指针函数,返回一个指针
{
if( list == NULL ) //如果指针指向空值,返回(链表为空)
return;
List* new_list = NULL; //定义一个新的空链表(新的结构体指针指向空)
List* next_node; //定义一个指针指向链表下一个节点
while( list != NULL ) //如果不是空链表,执行
{
next_node = list->next; //用指针指向链表下一个节点,
list->next = new_list; //该节点指向新的链表地址
new_list = list; //新链表指针指向链表
list = next_node; //链表指向下一个节点
}//while
return new_list; 返回新的链表
}
算法需要注意的地方就是关于指针的操作,其中在对list操作时,一定要把list->next保存起来。
4. 算法分析
算法的复杂度为O(n)。
方法二:使用三个指针遍历单链表,逐个链接点进行反转。
typedef struct List
{
int data;
struct List* next
}list;
list * reverselist(list * head)
{
if(head==NULL||NULL==head->next)
return head;
list * p,*q,*r;
p=head; // p指向head
q=head->next; //q指向head->next
head->next=NULL; //head->next指向NULL
}
while(q){
r=q->next; //r指向q->next
q->next=p; //q->next指向p
p=q; //p指向q
q=r;//q指向r
}
head=p;//head指向p
return head;
//删除链表节点
s=p->next;
p->next=s->next;
free(s);
//插入链表节点
s->data=x; //给节点装值
s->next=p->next;
p->next=s;