C语言链表
C语言链表
链表是一个非常重要的数据结构。更数组相比,它更加的灵活。关于链表的基本操作有:
- 创建(头插 和 尾插方法)
- 插入
- 删除
1、链表的创建之尾插法
首先,尾插法的方法创建。
tail->next = newPtr;
tail = newPtr;
意思就是:
让tail这个尾节点,先指向head(头节点),当有新节点创建时,让tail->next指针指向新节点(newPtr),然后将newPtr赋给尾节点。
2、链表的创建之头插法:
newPtr->next = head->next;
head->next = newPtr;
头插法,创建的链表顺序相反。
头指针不断的往前移动,头指针的next,就是新的节点(newPtr)
3、链表的插入
主要是通过指针的移动来实现
三种情况:
1、插入成为头结点
if(头节点==空){
head = newPtr;
head->next = NULL;
}
2、往中间插入
//判断是否要移动指针
while(插入的节点>头节点的值 && 头节点的next不等于NULL){
//移动指针
movePtr = headPtr;
headPtr = headPtr->next;
}
if(插入的节点<headPtr的值){
//先接后断原则
newPtr->next = headPtr;
movePtr->next = newPtr;
}else{
3、插入成为尾节点
headPtr->next = newPtr;
newPtr->next = NULL;
}
4、删除节点
一般从第二个节点开始删,头节点不存在数据域。所以:
ptr1 = head;
ptr2 = head->next;//从第二个节点开始
while(ptr2!=NULL){
if(ptr2->val == deleteNum){
//删除节点并释放空间
ptr1->next = ptr2->next;
free(ptr2);
}else{
//指针下移
ptr1 = ptr2;
ptr2 = ptr2->next;
}
}
//插入和删除;主要思想就通过相邻的两个指针不断移动,判断要执行的操作:
ptr1 = ptr2;
ptr2 = ptr2->next;
区分:
ptr = ptr->next ;意思是ptr这个指针下移一个位置;
ptr->next = ptr1;意思是ptr的next指向ptr1;
代码实例:
#include<stdio.h>
#include<malloc.h>
#include <stdbool.h>
#include<unistd.h>
//定义节点结构
struct LinkTable{
int val;
struct LinkTable *next;
}LinkList;
/**
*尾插法建立链表
*/
struct LinkTable *createLink(n){
struct LinkTable *head,*node,*tail;
int i;
head = (struct LinkTable*)malloc(sizeof(struct LinkTable));
tail = head;
for(i=0;i<n;i++){
//malloc 返回void型(struct LinkTable*)强制转换
node = (struct LinkTable*)malloc(sizeof(struct LinkTable));//动态分配内存
// node->val = i;
printf("请输入第%d个节点的值:",i+1);
scanf("%d",&node->val);
tail->next = node;
tail = node;
}
tail->next = NULL;
return head;
}
/**
* 头插法建立链表
*/
struct LinkTable *createLinkbyHead(int n){
struct LinkTable *head,*node;
int i;
head = (struct LinkTable*)malloc(sizeof(struct LinkTable));
for(i=0;i<n;i++){
node = (struct LinkTable*)malloc(sizeof(struct LinkTable));
printf("请输入第%d个节点的值:",i+1);
scanf("%d",&node->val);
node->next = head->next;
head->next = node;
}
return head;
}
/*删除*/
struct LinkTable *deleteLink(struct LinkTable *head,int deleteNum){
struct LinkTable *prePtr,*afterPtr;
int flag = 0;
prePtr = head;
afterPtr = head->next;
while(afterPtr!=NULL){
if(afterPtr->val == deleteNum){
flag = 1;
prePtr->next = afterPtr->next;
free(afterPtr);
}else{
prePtr = afterPtr;
afterPtr = afterPtr->next;
}
}
if(flag == 1){
printf("删除成功");
}else{
printf("删除失败");
}
return head;
}
/**
* 插入节点
*/
struct LinkTable *insertLink(struct LinkTable *head,int insert){
struct LinkTable *headPtr,*newPtr,*movePtr;
headPtr = head->next;//从第二个节点开始算,作为头结点
newPtr = (struct LinkTable*)malloc(sizeof(struct LinkTable));
newPtr->val = insert;
//1、判断是否需要移动指针
while((newPtr->val > headPtr->val)&&(headPtr->next!=NULL)){
//插入节点的val > 头节点的val
//头节点的next不是空
movePtr = headPtr;
headPtr = headPtr->next;
}
//2、往中间插入
if(newPtr->val < headPtr->val){
//先连后断
newPtr->next = headPtr;
movePtr->next = newPtr;
}else{
//往尾部插入
headPtr->next = newPtr;
newPtr->next = NULL;
}
return head;
};
/**
* 打印
*/
void printLink(struct LinkTable *head){
struct LinkTable *ptr;
if(head == NULL){
printf("没有节点存在");
}
for(ptr=head->next;ptr!=NULL;ptr=ptr->next){
if(ptr->next == NULL){
printf("%d",ptr->val);
}else{
printf("%d->",ptr->val);
}
}
printf("\n");
}
int main(){
struct LinkTable *createLink(int n);
struct LinkTable *createLinkbyHead(int n);
struct LinkTable *insertLink(struct LinkTable *head,int insert);
struct LinkTable *deleteLink(struct LinkTable *head,int deleteNum);
void printLink(struct LinkTable *head);
struct LinkTable *head;
int insert;
int deleteNum;
head=NULL;
head = createLink(3);
// head = createLinkbyHead(3);
int i;
for(i=0;i<3;i++){
printf("请输入要插入的数字:");
scanf("%d",&insert);
head = insertLink(head,insert);
}
printLink(head);
printf("请输入要删除的数字");
scanf("%d",&deleteNum);
head = deleteLink(head,deleteNum);
printLink(head);
return 0;
}