线性表的顺序存储结构最大的缺点在于:每次需要插入或者删除元素时,需要移动大量的元素,增加算法的时间复杂度。
链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素,这些存储单元可以是连续的,也可以是不连续的。单链表是由n个链结成的一个链表,即为线性表的链式存储结构,链表中的每个结点只包含一个指针域。
头指针:链表中第一个结点的存储位置叫做头指针。头指针是指向链表第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识的作用,所以常用头指针来作为链表的名字,无论链表是否为空,头指针均不能为空,头指针是链表中的必要元素。
创建一个单链表:
1.声明单链表的数据结构
struct Node{
int data;
Node *next;
} *LinkList;
2.创建一个单链表,并返回链表的头指针
Node *CreateLinkList(int n){
//声明一个头指针,作为函数返回值,表示当前创建的链表
Node *head;
Node *p;
//初始化链表的头结点
LinkList=new Node;
//初始化头指针
head=LinkList;
LinkList->next=NULL;
//向链表中填充数据
for(auto i=0;i<n;i++){
p = new Node;
p->data=i;
p->next=LinkList->next;
LinkList->next=p;
}
return head;
}
3.循环遍历单链表中的数据元素
//head代表需要遍历的链表的头指针
void ForeachLinkList(Node *head){
Node *p=head->next;
while(p!=NULL){
cout<<p->data<<endl;
p=p->next;
}
}
4.输出链表中的元素
int main(){
Node *head=CreateLinkList(10);
ForeachLinkList(head);
return 0;
}
5.取得指定位置的元素
//head代表要查找链表的头指针
//n代表要查找元素的位置
int GetElement(Node *head,int n){
int j=1;
Node *p=head->next;
while(p!=NULL&&j<n){
p=p->next;
j++;
}
return (p->data);
}
从单链表中插入和删除数据过程
<插入>从单链表的第n个位置中插入数据算法思路
1.声明指针p指向链表的头结点,声明并初始化j从1开始。
2.当j小于n时,遍历链表,移动指针p,指向下一个结点,j值累加
3.如果到链表末尾p指针为空,则要删除的结点不存在。
向链表中插入数据过程如下:
bool InsertElement(Node *head, int n, int element) {
int j = 0;
Node *p, *newNode;
p = head;
while (p != NULL && j < n) {
p = p->next;
j++;
}
if (p == NULL || j > n) {
return false;
}
newNode = new Node;
newNode->data = element;
newNode->next = p->next;
p->next = newNode;
return true;
}
<删除>从链表中第n个位置删除数据算法思路
1.声明一个指针p指向链表的头结点,初始化j的值从1开始
2.当j小于n时,遍历链表,后移指针p,使其指向链表的下一个结点,j的值累加1;
3.如果p的值为空,说明要删除的结点不存在;
向链表中删除数据过程如下:
//从链表中删除数据
bool DeleteElement(Node *head, int n) {
int j = 0;
Node *p, *deleteNode;
p = head;
while (p&&j < n) {
p = p->next;
j++;
}
if (p == NULL || j > n) {
return false;
}
deleteNode = p->next;
p->next = deleteNode->next;
delete deleteNode;
return true;
}
主函数中测试代码如下:
int main()
{
Node *head = CreateLinkList(10);
cout << "-----分割线-------" << endl;
cout << "初始链表中的数据元素" << endl;
ForeachLinkList(head);
cout << "从单链表中获取第五个结点的数据值" << endl;
cout << GetElementFromLinkList(head, 7) << endl;
cout << "-----分割线-------" << endl;
InsertElement(head, 3, 88);
cout << "向链表的第三个位置插入数据后,链表中的元素如下" << endl;
ForeachLinkList(head);
cout << "-----分割线-------" << endl;
DeleteElement(head, 2);
cout << "删除链表中第二个位置的数据后,链表中的元素如下" << endl;
ForeachLinkList(head);
return 0;
}
输出:
工程文件地址:https://github.com/USuperMe/SinglyLinkList.git