1.单链表的存储
我们将这种只带有一个指针域的线性表称为单链表。
链表中第一个结点的存储位置叫做头指针。
单链表的第一个结点钱附设一个结点,称为头结点。
上一节我们提到过,线性表的最后一个元素是没有直接后继的,所以在链式存储中,我们将最后一个结点的指针域设置为null.
typedef struct LNode
{
int data; //数据域
struct LNode *next;//指针用
}LNode,*LinkList; //定义节点,以及头指针
这里直接定义的*LinkList类型是直接指向结构体的指针,这样如果用LinkList定义的时候比如说,LinkList L,L定义就是一个指针类型变量,如果要对结构体里面的东西进行操作的时候,对于指针类型要用L->date,L->next,必须要这样,但是如果要使用'.'运算符的话,必须要使用(*L).date、(*L).next,而此时*L可以直接当作一个变量来处理了。
2.建立链表
int creatlist(LinkList & L, int a[],int n)
{//逆位序输入数组a中的n个数,建立一个带有头结点的单链表。
LinkList p;//定义一个指向Node结构体的指针
int i;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //先建立一个带有头结点的空链表
L->data = n; //头结点数据域存好元素个数
for (i = n-1; i >=0; i--) //逆序输入n个元素
{
p = (LinkList)malloc(sizeof(LNode)); //生成新结点
p->data = a[i]; //赋值
p->next = L->next; //将头结点的指针指向刚申请的新结点
L->next = p; //将新申请结点的头指针把头结点连起来
}
return 0;
}
3.链表的查找
int search(LinkList &L, int i)
{
LinkList q; //定义一个指向LNode结构体的指针
q = L->next; //将头结点的指针指向q
int j = 1;
while (j<i)
{
q = q->next; //一直向下进行遍历,进行查找,对于原来的链表L是没有影响的
j++;
}
return q->data; //找到后返回找到的值
}
4.链表插入
void setin(LinkList L, int e, int i)
{
LinkList p = L, q; //定义两个指向LNode结构体的指针,并且让p的指针指向L的头结点
int j = 1;
q = (LinkList)malloc(sizeof(LNode)); //申请一个结点
while (p->next!=NULL&&j<i) //进行遍历来查找插入点
{
p = p->next;
j++;
}
q->data = e; //赋值
q->next = p->next; //将原先指向p的下一个元素的指针赋给q,让q指向,完成了指针的传递
p->next = q; //这时候再让p的指针指向q,将整条链连贯起来
}
5.链表的删除
void Delete(LinkList &L, int i)
{
int j = 1;
LinkList p = L, q; //定义两个指向LNode结构体的指针p,q,并且让p指向L的头结点
while (p->next&&j<i) //遍历找位置
{
p = p->next;
j++;
}
q = p->next; //此时的q为要删除的元素
p->next = q->next; //将删除元素指向下一个元素的指针赋值给它之前的元素,这样就直接把
// 删除元素从链表中给断掉。
}
6.链表的元素值的修改
void change(LinkList L, int i, int e)
{
LinkList p = L; //定义指向结构体的指针p,并且让p指针指向L的头结点
p = p->next; //让p指向第一个元素
int j = 1;
while (j<i)//遍历查找
{
p = p->next;
j++;
}
p->data = e; //找到后赋值进行修改,应为在该地址上改的,因为地址对应是相等的所以L的值
//也就修改了。
}
7.链表的就地逆置
就地逆置的思想:首先先把头结点和第一个元素连接断开,并且让头结点指向NULL,这样依次将第一、二、三...元素取出来,先插入第一个,让头结点指向一个元素,元素1指向NULL,再插入第二个元素,让头结点再指向第二个元素,第二个元素指向第一个元素....
void reverse(LinkList L)
{
LinkList p, q; //定义指向结构体的指针p,q
p = L->next; //让p的指向第一个元素
L->next = NULL; //头结点指向NULL,为空
while (p!=NULL)
{
q = p; //将q指向p的头指针
p = p->next; //p指针向下移动一个元素
q->next = L->next; //将原先L指向的元素让q指向
L->next = q; //让新结点头指针和L的头指针相连
}
}
8.下面附上一个完全的代码:关于建立、查找、删除、更新、就地逆置、输出
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma warning(disable:4996)
typedef struct LNode
{
int data;
struct LNode *next;
}LNode,*LinkList;
int creatlist(LinkList & L, int a[],int n)
{
LinkList p;
int i;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
L->data = n;
for (i = n-1; i >=0; i--)
{
p = (LinkList)malloc(sizeof(LNode));
p->data = a[i];
p->next = L->next;
L->next = p;
}
return 0;
}
void putlist(LinkList &L)
{
LinkList p;
p = L->next;
while (p!=NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int search(LinkList &L, int i)
{
LinkList q;
q = L->next;
int j = 1;
while (j<i)
{
q = q->next;
j++;
}
return q->data;
}
void Delete(LinkList &L, int i)
{
int j = 1;
LinkList p = L, q;
while (p->next&&j<i)
{
p = p->next;
j++;
}
q = p->next;
p->next = q->next;
}
void setin(LinkList L, int e, int i)
{
LinkList p = L, q;
int j = 1;
q = (LinkList)malloc(sizeof(LNode));
while (p->next!=NULL&&j<i)
{
p = p->next;
j++;
}
q->data = e;
q->next = p->next;
p->next = q;
}
void reverse(LinkList L)
{
LinkList p, q;
p = L->next;
L->next = NULL;
while (p!=NULL)
{
q = p;
p = p->next;
q->next = L->next;
L->next = q;
}
}
void change(LinkList L, int i, int e)
{
LinkList p = L;
p = p->next;
int j = 1;
while (j<i)
{
p = p->next;
j++;
}
p->data = e;
}
int main()
{
LinkList L;
int a[500];
int n;
int m;
printf("\n请输入元素个数:");
scanf("%d", &n);
printf("\n请依次输入元素:");
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
creatlist(L,a,n);
printf("\n输出链表中所有元素:");
putlist(L);
printf("\n请输入要查找的位置:");
scanf("%d", &n);
m=search(L,n);
printf("\n第%d元素为%d",n,m);
printf("\n请输入要删除的元素的位置:");
scanf("%d", &n);
Delete(L, n);
printf("\n输出链表所有元素:");
putlist(L);
printf("\n请输入要插入的元素和其位置:");
scanf("%d %d", &m, &n);
setin(L,m,n);
printf("\n输出链表所有元素:");
putlist(L);
printf("\n链表就地逆置输出:");
reverse(L);
putlist(L);
printf("\n请输入修改的元素的位置和修改后的值:");
scanf("%d %d", &n, &m);
change(L, n, m);
putlist(L);
return 0;
}
下面转一篇写的关于存储结构的问题的博客:https://www.cnblogs.com/dangnianhefeng/p/5034260.html
下面一篇博客是关于结构体里的 '.'运算符和 '->'运算符的区别的:https://www.cnblogs.com/limeina/p/3665568.html
欢迎大家提出宝贵意见,感激不尽!!!