链表的基本概念:
结点包括数据域和指针域
链表由很多个结点链接成,第一个结点的存储位置叫头指针,最后一个结点的指针为空。
头指针:链表第一个结点的存储位置
头结点:在单链表的第一个结点前附设的一个结点,为了 操作的统一的方便设立的。
结点的一般形式:
typedef struct Node{
int id; //数据域
char name[50]; //数据域
struct Node* next; //指针域,用来指向下一个节点
}Node;
接下来实现链表的基本操作,增删改查
#include <stdio.h>
#include <stdlib.h>
//数据域结构
typedef struct Element{
int id;
char name[50];
}Element;
//定义结点
typedef struct Node{
Element data; //数据域
struct Node* next; //指针域
}Node;
//定义头结点
typedef struct Linklist{
Node* next; //定义头指针,以便统一链表的结点的插入与删除
int length; //记录链表长度
}Linklist;
Element data[]={
{1,"大帅比1"},
{2,"大帅比2"},
{3,"大帅比3"},
{4,"大帅比4"}
};
//初始化链表 传入链表,初始化的元素和个数 (初始化)
void InitLinklist(Linklist* linklist,Element* datas,int length);
//链表插入 入链表,插入的元素和插入的位置(增)
void InsertLinklist(Linklist* linklist,Element data,int position);
//链表的删除 (删)
void DeleteLinklist(Linklist* linklist,int position);
//链表的修改 (改)
void ModifyLinklist(Linklist* linklist,int position);//
//链表打印 (查)
void PrintLinklist(Linklist* linklist);
int main(void)
{
Linklist linklist;
InitLinklist(&linklist,data,sizeof(data)/sizeof(data[0]));
PrintLinklist(&linklist);
//这里展示一下删除第二个元素
printf("删除第二个元素:\n") ;
DeleteLinklist(&linklist,2);
PrintLinklist(&linklist);
return 0;
}
//初始化链表 传入链表,初始化的元素和个数
void InitLinklist(Linklist* linklist,Element* datas,int length)
{
//一定要把链表长度初始化为0
linklist->length = 0;
int i;
for(i = 0 ;i < length ;i++)
{
InsertLinklist(linklist,data[i],i+1);
}
}
//链表插入 入链表,插入的元素和插入的位置
void InsertLinklist(Linklist* linklist,Element data,int position)
{
//1创建空结点并为数据赋值
Node* newnode = (Node*)malloc(sizeof(Node)); //申请空间
newnode->data = data; //存储数据
newnode->next = NULL; //指针指向空
//2找到要插入的并对接前面的结点
if(position == 1) //如果插入的位置是第一个
{
linklist->next = newnode; //直接让头指针指向这个结点即可
linklist->length ++; //长度加1
return; //这里要注意
}
//如果不是第一个,通过循环找到要插入的节点位置
Node* crrnode = linklist->next; //通过crrnode来遍历,找到要插入的结点的位置
int i;
for(i = 1 ; crrnode && i < position-1;i++)
{
crrnode =crrnode->next;
}
//循环完后,crrnode是指向pos-1的位置,即要插入的位置的前一个结点
//3将节点插入并对接前面的结点
if(crrnode)
{
newnode->next = crrnode->next;//crrnode是指向pos-1的位置,它的->next就是要插入的pos的位置,对接上后一个结点
crrnode->next = newnode;//对接前一个结点
linklist->length ++;//长度++
}
}
//链表打印 (查)
void PrintLinklist(Linklist* linklist)
{
Node* curnode = linklist->next;
if(!curnode)
{
printf("链表为空!");
linklist->length = 0;
return;
}
while(curnode)
{
printf("%d %s\n",curnode->data.id,curnode->data.name);
curnode=curnode->next;
}
}
void DeleteLinklist(Linklist* linklist,int position)
{
Node* node = NULL;
if(position == 1)
{
node = linklist->next;
if(node)
{
linklist->next=node->next;
free(node);
linklist->length--;
return;
}
printf("没有第一个结点");
return;
}
Node* prenode;
node = linklist->next;
int i;
for(i = 1 ; node && i < position;i++)
{
prenode = node;
node = node->next;
}
if(node)
{
prenode->next = node->next;
free(node);
linklist->length--;
}
}