一、简介
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序来实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域(data),另一个是存储下一个结点地址的指针域(next),另外还有一个头节点(plist)。
二、存储结构
注意:1.头节点中无数据
2.一个头节点的空间复杂度为O(1)。
三、代码
头文件:list.h
#pragma once
//带头结点的单链表,单链表的尾节点的next为NULL
//链表中不使用下标
typedef struct Node
{
int data;//数据
struct Node *next;//后继指针
}Node,*List;//List=Node*
//初始化
void InitList(List plist);
//头插,将数据插入到链表的第一个位置
bool Insert_head(List plist,int val);
//尾插,将数据插入到链表的末尾
bool Insert_tail(List plist,int val);
//将数据val,插入到plist中的pos位置
bool Insert_pos(List plist,int val,int pos);//不常用
//在plist中查找关键字key,成功返回节点地址,失败返回NULL
Node *Search(List plist,int key);
//删除plist中的第一个key
bool Delete(List plist,int key);
//清空数据
void Clear(List plist);
//销毁链表
void Destroy(List plist);
//显示数据
void Show(List plist);
//******考试最多*****//
//链表逆置
void Reverse(List plist);
源文件:list.cpp
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "list.h"
//初始化
void InitList(List plist)
{
assert(plist != NULL);
plist->next = NULL;
}
//头插法,将数据插入到链表的第一个位置
bool Insert_head(List plist,int val)
{
Node *p=(Node *)malloc(sizeof(Node));
assert(p!=NULL);
p->data=val;
p->next=plist->next;
plist->next=p;
return true;
}
//尾插法,将数据插入到链表的末尾
bool Insert_tail(List plist,int val)
{
Node *p;
Node *q=(Node *)malloc(sizeof(Node));
q->data=val;
for(p=plist;p->next!=NULL;p=p->next);//找尾巴
//q插入在p的后面
q->next=p->next;//q->next==NULL
p->next=q;
return true;
}
//在plist中查找关键字key,成功返回节点地址,失败返回NULL
Node *Search(List plist,int key)
{
Node *p;
for(p=plist->next;p!=NULL;p=p->next)
{
if(p->data==key)
{
return p;
}
else
return NULL;
}
}
//查找key的前驱节点
static Node *SearchPri(List plist,int key)
{
Node *p;
for(p=plist;p->next!=NULL;p=p->next)
{
if(p->next->data==key)
{
return p;
}
}
return NULL;
}
//删除plist中的第一个key
bool Delete(List plist,int key)
{
Node *p=SearchPri(plist,key);
if(p==NULL)
{
return false;
}
Node *q=p->next;
p->next=q->next;//p->next=p->next->next
free(q);
return true;
}
//清空数据,删除所有的数据节点
void Clear(List plist)
{
Destroy(plist);
}
//销毁链表
void Destroy(List plist)
{
Node *p;
while(plist->next!=NULL)
{
p=plist->next;
plist->next=p->next;
free(p);
}
Node *p=plist->next;
Node *q;
plist->next=NULL;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
}
//显示数据
void show(List plist)
{
Node *p;
for(p=plist->next;p!=NULL;p=p->next)
{
printf("%d",p->data);
}
printf("\n");
}
主函数:test.cpp
#include <vld.h>
#include <stdio.h>
#include "list.h"
int main()
{
Node head;
InitList(&head);
for(int i=0;i<10;i++)
{
Insert_tail(&head,i);
}
Delete(&head,0);
Delete(&head,5);
Delete(&head,9);
Delete(&head,20);
Show(&head);
Destroy(&head);
Destroy(&head);
return 0;
}
四、总结
for(p=plist;p->next!=NULL;p=p->next) 对链表的结构进行修改(插入、删除)
for(p=plist->next;p!=NULL;p=p->next) 只遍历链表中的数据元素(查找、打印)