链表
学习《数据结构》的线性表后,发现删除和插入元素非常耗费时间,所以就有了链表的这个结构。
链表的特殊在于:一个元素的数据存储在结点中,每个结点有一个指向下一个结点地址的指针,这样这些结点就可以不是连续的地址了,结点可以任意在某个地址。所以因为它可以通过指针指向下一个节点的地址,这样节点与节点之间就形成了一条链,顾名思义“链表”。
注:
- 一个链表的尾节点的指针指向为NULL。
- 数据元素之间的逻辑关系是由结点中的指针指示的
- 一般一个链表会有一个头节点指向链表的头元素,这个头节点可以为NULL,也可以存储数据;有了这个头节点在一些链表的操作上会显得十分方便。
具体代码如下:
/*
LinkList implementation
Author: zzj
Date : 17-6-13
*/
#include<cstdio>
#include<cstdlib>
/*定义单链表结构*/
typedef struct node{
int data;
struct node *next;
}Node,*LinkList;
/*创建新链表,尾插法L*/
void CreatList_L(LinkList &L,int n)
{
int a;
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;//建立一个带头结点的单链表,L为头结点
Node *p = L;
for(int i=0;i<n;i++)
{
Node *s = (LinkList)malloc(sizeof(Node));
scanf("%d",&a);
s->data = a;
p->next = s;
s->next=NULL;
p = p->next;
}
}
/*在链表L的loc位置上插入k*/
/*如果要在loc上插入元素,则必须让指针指向loc-1的位置上,这样才能使元素插入到loc上*/
bool Insert(LinkList &L, int k, int loc)
{
loc--;
Node *p = L->next;
while(--loc)
{
p = p->next;
if(!p) return false;//如果插入的元素位置大于链表长度加1,则失败
}
Node *s = (Node*)malloc(sizeof(Node));//定义新的结点s
s->data = k;
s->next = p->next; //s指向的下一个位置是p指向的下一个元素的位置
p->next = s; //此时p指向的下一个元素就是s
return true;
}
/*在链表L上删除loc位置的元素,并用e返回其值*/
bool Delete(LinkList &L, int loc, int &e)
{
loc--;
Node *p = L->next;
while(--loc)
{
p = p->next;
if(!p->next) return false;//如果删除元素的位置超过链表长度,则失败
}
Node *q = p->next; //定义指针q指向p的下一个元素
p->next = q->next;
e = q->data;
free(q);//释放内存
return true;
}
/*遍历整个链表L*/
void Traverse_L(LinkList &L)
{
Node *p = L->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int main()
{
LinkList L = NULL;
while(1)
{
printf("1.创建链表...");
printf("2.遍历链表...");
printf("3.插入元素...");
printf("4.删除元素...");
printf("5.退出...\n");
printf("请选择:");
int choose;
scanf("%d", &choose);
if(choose == 5) break;
switch(choose)
{
case 1://创建链表
if(L) printf("链表已经创建!!\n");
else
{
printf("输入链表的元素个数:");
int n;
scanf("%d",&n);
printf("输入链表的元素:");
CreatList_L(L,n);
printf("\n");
}
break;
case 2://遍历链表
if(!L) printf("warning!请创建新的链表\n");
else{
printf("遍历链表的元素:");
Traverse_L(L);
printf("\n");
}
break;
case 3://插入元素
int k, loc;
if(!L) printf("warning!请创建新的链表\n");
else{
printf("输入插入的元素和位置:");
scanf("%d%d", &k, &loc);
if(!Insert(L, k, loc))
{
printf("插入失败\n");
}
printf("\n");
}
break;
case 4://删除元素
if(!L) printf("warning!请创建新的链表\n");
else{
printf("输入删除的元素位置: ");
int e;
scanf("%d", &loc);
if(!Delete(L, loc, e))
{
printf("删除失败\n");
}
else printf("删除元素为%d\n",e);
printf("\n");
}
break;
}
}
return 0;
}