反转链表用什么字母表达(单链表表示的三种方法)
对于线性表来说, 总得有个头尾,头部做为基准地址,如数组的数组名,链表的头指针尾部做为结束的标志,数组使用一个长度属性来标识数组的结束位置,字符串使用转义字符'\0',链表使用NULL指针来标识结束位置,我来为大家科普一下关于反转链表用什么字母表达?下面希望有你要的答案,我们一起来看看吧!
反转链表用什么字母表达
对于线性表来说, 总得有个头尾,头部做为基准地址,如数组的数组名,链表的头指针。尾部做为结束的标志,数组使用一个长度属性来标识数组的结束位置,字符串使用转义字符'\0',链表使用NULL指针来标识结束位置。
我们知道,数组的全部元素是集中存储,数组的基准地址是第一个元素的地址,也就是数组名的值,其它元素的索引都是一个整型常量,对元素的访问就是基准地址相对于索引的偏移,所以数组元素可以随机访问。
链式存储是分散存储,通过节点的指针域来建立一个节点与其下一个邻接节点的联系。链式存储的头指针虽然也是整个链式数据结构的基准地址,但要找到某一节点,需要顺序访问,从头节点开始,顺着每一个节点的指针域的值,一个节点一个节点地挼。
我们把链表中第一个节点的存储位置叫做头指针, 那么整个链表的存取就必须是从头指针开始进行了。之后的每一个节点, 其实就是上一个的后继指针指向的位置。有时,我们为了更加方便地对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头节点。头节点的数据域可以不存储任何信息,谁叫它是第一个呢,有这个特权。也可以存储如线性表的长度等附加信息,头节点的指针域存储指向第一个节点的指针。
头指针 |
头节点 |
1 头指针是指链表指向第一个节点的指针,若链表有头结点,则是指向头结点的指针 |
1 头结点是为了操作的统一和方便而设立的,放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度) |
2 头指针具有标识作用, 所以常用头指针冠以链表的名字 |
2 有了头结点,对在第一个元素节点前插入节点和删除第一节点,其操作与其它结点的操作就统一了 |
3 无论链表是否为空, 头指针均不为空。头指针是链表的必要元素 |
3 头结点不一定是链表必须要素 |
是否使用头节点,在实现链表的常用操作时代码的写法稍有区别,使用头节点的方法代码较为简洁。同时,也可以将这个表头节点指针封装到一个结构体中,并在结构体中增加链表长度等信息。
1 使用头节点的链表表示
加头结点的优点:
1)链表第一个位置的操作无需特殊处理;
2)将空表和非空表的处理统一。
#include <stdio.h>
#include <malloc.h>
typedef struct Node{
int data;
struct Node * next;
}Node,*pNode;
pNode createList() // 头节点是空节点
{
pNode head = (pNode)malloc(sizeof(Node));
if(head==NULL)
{
printf("malloc failed!\n");
return head;
}
head->data = 0;
head->next = NULL;
return head;
}
int insert(pNode head, int data) // 头插法
{
pNode newNode = (pNode)malloc(sizeof(Node));
if(newNode==NULL)
{
printf("malloc failed!\n");
return -1;
}
newNode->data = data;
newNode->next = head->next;
head->next = newNode;
return 0;
}
void printList(pNode head)
{
pNode cur = head->next;
while(cur){
printf("%d ",cur->data);
cur = cur->next;
}
}
void destroyList(pNode head)
{
pNode p = head;
pNode q = p->next;
while(q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
int main()
{
pNode head = createList();
for(int i=0;i<10;i )
insert(head,i 1);
printList(head);
destroyList(head);
getchar();
return 0;
}
/*
10 9 8 7 6 5 4 3 2 1
*/
2 不使用头节点的链表表示
#include <stdio.h>
#include <malloc.h>
typedef struct Node{
int data;
struct Node * next;
}Node,*pNode;
int insert(pNode* head, int data) // 头插法,头部是一个实节点
{
pNode newNode = (pNode)malloc(sizeof(Node));
if(newNode==NULL)
{
printf("malloc failed!\n");
return -1;
}
newNode->data = data;
if(head==NULL)
newNode->next=NULL;
else
newNode->next = *head;
*head = newNode;
return 0;
}
void printList(pNode head)
{
pNode cur = head;
while(cur){
printf("%d ",cur->data);
cur = cur->next;
}
}
void destroyList(pNode head)
{
pNode p = head;
pNode q = p->next;
while(q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
int main()
{
pNode head = NULL;
for(int i=0;i<10;i )
insert(&head,i 1);
printList(head);
destroyList(head);
getchar();
return 0;
}
/*
10 9 8 7 6 5 4 3 2 1
*/
3 链表和链表节点用不同的结构体来表示
链表用一个结构体来描述,封装一个节点指针做表头,并增加一个链表长度变量,需要时也可以增加一个节点指针做表尾。
#include <stdio.h>
#include <malloc.h>
typedef struct Node{
int data;
struct Node * next;
}Node,*pNode;
typedef struct List{
pNode head;
int size;
}List,*pList;
pList createList()
{
pList pl = (pList)malloc(sizeof(List));
if(pl==NULL)
{
printf("malloc failed!\n");
return pl;
}
pl->head = (pNode)malloc(sizeof(Node));
if(pl->head==NULL)
{
printf("malloc failed!\n");
return NULL;
}
pl->head->data = 0;
pl->head->next = NULL;
pl->size = 0;
return pl;
}
int insert(pList pl, int data) // 头插法,头部是一个空节点
{
pNode newNode = (pNode)malloc(sizeof(Node));
if(newNode==NULL)
{
printf("malloc failed!\n");
return -1;
}
newNode->data = data;
newNode->next = pl->head->next;
pl->head->next = newNode;
pl->size ;
return 0;
}
void printList(pList pl)
{
pNode cur = pl->head->next;
while(cur){
printf("%d ",cur->data);
cur = cur->next;
}
}
void destroyList(pList* pl)
{
pNode p = (*pl)->head;
pNode q = p->next;
while(q!=NULL){
free(p);
p=q;
q=p->next;
}
free(p);
free(*pl);
}
int main()
{
pList pl = createList();
for(int i=0;i<10;i )
insert(pl,i 1);
printList(pl);
destroyList(&pl);
getchar();
return 0;
}
/*
10 9 8 7 6 5 4 3 2 1
*/
-End-
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com