单链表简介
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
链接存储方式
1.用一组任意的存储单元来存放线性表的结点
2.链表中结点的逻辑次序和物理次序不一定相同,在存储每个结点值的同时,还必须存储指示起后继节点的地址信息。
链表的结点结构
┌───┬───┐
│data │next │
└───┴───┘
data域--存放结点值的数据域。
next域--存放结点的直接后继的地址(位置)的
指针域(链域)。
注意:①链表通过每个结点的指针域将链表的n个结点安妮逻辑循序连接在一起的。
②每个结点只有一个指针域的链表称为单链表。
③链表由头结点唯一确定,单链表可以用头指针的名字来命名。
④尾结点无后继结点,故尾结点的指针域为NULL。
typedef struct node{
int data; //数据域
struct node * next; //指针域
}Node, *pNode; //别名
单链表的常见操作
1.创建链表
pNode createList(){
int len, val; //len存放链表长度,val存放结点数据值
pNode pHead = (pNode)malloc(sizeof(Node)); //给头结点动态分配内存
if(pHead == NULL){ //判断分配内存是否成功
printf("动态分配内存失败");
exit(-1);
}
pNode pTail = pHead; //定义尾结点
pTail->next = NULL; //尾结点无后继指针
printf("请输入创建链表长度len:");
scanf("%d", &len);
for(int i=0; i<len; i++){
pNode pNew = (pNode)malloc(sizeof(Node)); //定义新结点,动态分配内存
if(pNew == NULL){
printf("动态分配内存失败");
exit(-1);
}
printf("请输入第%d个结点数值:", i+1);
scanf("%d", &val);
pNew->data = val; //新结点数据域存放数值
pTail->next = pNew; //令尾结点指针指向新结点
pNew->next = NULL; //当尾结点指向新结点时,新结点成为最后一个结点,其指针域应为空
pTail = pNew; //令尾结点指向最后一个结点
}
return pHead;
}
2. 遍历链表
void traversalList(pNode p){
while(p->next){ //判断结点的指针域是否为空
p = p->next; //指向下一个结点
printf("%d ", p->data); //打印结点数值
}
printf("\n");
}
3.计算链表长度
int length(pNode p){
pNode L = p->next; //定义临时结点指向首结点
int len = 0; //存放链表长度
while(L){ //判断首结点是否存在
len++;
L = L->next;
}
return len;
}
4.判断链表为空
bool isEmpty(pNode p){
if(!(p->next)) //判断首结点是否为空
return true; //
else
return false;
}
5.排序(从小到大)
void sortList(pNode p){
int len = length(p); //存放链表长度
for(int i=0; i<len-1; i++){
p = p->next; //外层每循环一次,指向下一个结点
pNode q = p->next; //定义新结点指向一个结点的下一个结点
for(int j=i+1; j<len; j++){ //一个结点与这个结点后面的每个结点依次比较
if(p->data > q->data){ //如果这个结点小于这个结点后面任意一个结点,互换值
int temp = p->data;
p->data = q->data;
q->data = temp;
}
q = q->next;
}
}
}
6插入(第n个结点的前面)
void insertList(pNode p, int pos, int val){
int i=0;
pNode pNew = (pNode)malloc(sizeof(Node)); //定义结点
if(!pNew){
printf("动态分配内存失败");
exit(-1);
}
pNew->data = val; //存放插入数据
while(i<pos-1 && p->next){ //寻找要插入结点的前一个结点
p = p->next;
i++;
}
if(i>pos-1 || !(p->next)){ //判断指针指向的位置是否正确
return;
}
else{
pNew->next = p->next;
p->next = pNew;
}
}
7.删除
void deleteList(pNode p, int pos){
int i = 0;
while(i<pos-1 && p->next){ //寻找删除结点的前一个结点
p = p->next;
i++;
}
if(i>pos-1 || !(p->next)){ //判断指针指向的位置是否正确
return;
}
else{
pNode q = p->next; //定义临时结点错放被删除结点
p->next = q->next; //指针指向的结点的指针域存放被删除结点的后继结点
free(q); //删除结点
q = NULL;
}
}
完整代码
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node * next;
}Node, *pNode;
pNode createList();
void traversalList(pNode p);
int length(pNode);
bool isEmpty(pNode);
void sortList(pNode);
void insertList(pNode, int, int);
void deleteList(pNode, int);
int main(void){
pNode p = createList();
return 0;
}
pNode createList(){
int len, val;
pNode pHead = (pNode)malloc(sizeof(Node));
if(pHead == NULL){
printf("动态分配内存失败");
exit(-1);
}
pNode pTail = pHead;
pTail->next = NULL;
printf("请输入创建链表长度len:");
scanf("%d", &len);
for(int i=0; i<len; i++){
pNode pNew = (pNode)malloc(sizeof(Node));
if(pNew == NULL){
printf("动态分配内存失败");
exit(-1);
}
printf("请输入第%d个结点数值:", i+1);
scanf("%d", &val);
pNew->data = val;
pTail->next = pNew;
pNew->next = NULL;
pTail = pNew;
}
return pHead;
}
void traversalList(pNode p){
while(p->next){
p = p->next;
printf("%d ", p->data);
}
printf("\n");
}
int length(pNode p){
pNode L = p->next;
int len = 0;
while(L){
len++;
L = L->next;
}
return len;
}
bool isEmpty(pNode p){
if(!(p->next))
return true;
else
return false;
}
void sortList(pNode p){
int len = length(p);
for(int i=0; i<len-1; i++){
p = p->next;
pNode q = p->next;
for(int j=i+1; j<len; j++){
if(p->data > q->data){
int temp = p->data;
p->data = q->data;
q->data = temp;
}
q = q->next;
}
}
}
void insertList(pNode p, int pos, int val){
int i=0;
pNode pNew = (pNode)malloc(sizeof(Node));
if(!pNew){
printf("动态分配内存失败");
exit(-1);
}
pNew->data = val;
while(i<pos-1 && p->next){
p = p->next;
i++;
}
if(i>pos-1 || !(p->next)){
return;
}
else{
pNew->next = p->next;
p->next = pNew;
}
}
void deleteList(pNode p, int pos){
int i = 0;
while(i<pos-1 && p->next){
p = p->next;
i++;
}
if(i>pos-1 || !(p->next)){
return;
}
else{
pNode q = p->next;
p->next = q->next;
free(q);
q = NULL;
}
}