单向链表相关操作
#include <stdio.h>
#include <stdlib.h>
#include "./03_LinklistFun.h"
typedef int datatype;
typedef struct linlst
{
union
{
int len;
datatype data;
}text;
struct linlst* next;
}Linklist;
//创建单链表
Linklist* Create_Linklist(void)
{
//在堆空间申请了头节点的空间,头节点的首地址存储在head指针中。
//head指针就是头指针
Linklist* head=(Linklist*)malloc(sizeof(Linklist));
if(NULL == head)
{
printf("单链表创见失败\n");
return NULL;
}
//初始化头节点中的len
head->next = NULL;
head->text.data=0;
return head;
}
//头插法
void insert_linkByHead(Linklist* head,int num)
{
//创建一个新的节点
Linklist* temp = (Linklist*)malloc(sizeof(Linklist));
temp->text.data=num;
temp->next=NULL;
//将temp头插法插入链表
temp->next = head->next;
head->next = temp;
//更新头节点中链表的长度
head->text.len++;
}
//尾插法
void insert_listByTail(Linklist* head,int num)
{
//创建新的节点
Linklist* temp=(Linklist*)malloc(sizeof(Linklist));
temp->text.data=num;
temp->next=NULL;
//找到节点p的位置:循环判断p->next是否为NULL
Linklist* p=head;
p=head;
while(p->next != NULL)
{
p=p->next;
}
//尾插法插入数据
temp->next=p->next;
p->next=temp;
//更新结点中链表的长度
head->text.len++;
}
//头删法
void del_LinkByhead(Linklist* head)
{
Linklist* temp= (Linklist*)malloc(sizeof(Linklist));
//判断链表是否为空
if(head->next == NULL)
{
printf("链表为空删除失败\n");
return;
}
//将要释放的节点地址另存
temp=head->next;
head->next=temp->next;
//释放结点
free(temp);
temp=NULL;
//更新头结点链表长度
head->text.len--;
}
//尾删法
void del_LinkBytail(Linklist* head)
{
Linklist* p=head;
//判断链表是否为空
if(head->next == NULL)
{
printf("链表为空删除失败\n");
return;
}
//循环方式找倒数2个结点p
while(p->next->next != NULL)
{
p=p->next;
}
//释放结点
free(p->next);
p->next=NULL;
//更新头结点链表长度
head->text.len--;
}
//按位置插入
void insert_linkByIndex(Linklist* head,datatype num,int n)
{
//判断插入位置是否合法
if(n<1)
{
printf("n=%d插入位置非法\n",n);
return;
}
//找要插入的位置的前一个节点位置
//若p指向NULL,则代表插入位置非法
Linklist* p = head;
for(int i=0;i<n-1;i++)
{
p=p->next;
if(NULL == p)
{
printf("插入位置非法\n");
return;
}
}
//创建一个新的节点
Linklist* temp=(Linklist*)malloc(sizeof(Linklist));
if(NULL == temp)
{
printf("创建结点失败,插入失败\n");
return;
}
temp->text.data=num;
temp->next = NULL;
//将temp插入到p结点的后一个位置
temp->next=p->next;
p->next=temp;
//更新头结点中链表的长度
head->text.len++;
return;
}
//按位置删除
void del_linkByIndex(Linklist* head,int n)
{
//判断链表是否为空
if(NULL == head->next)
{
printf("链表为空,按位置删除失败\n");
return;
}
//判断删除位置是否合法
if(n<1)
{
printf("n=%d删除位置非法\n");
return;
}
//找到要删除位置的前一个结点位置
Linklist* p = head;
for(int i=0;i<n-1;i++)
{
p=p->next;
if(NULL == p->next)
{
printf("删除位置非法\n");
return;
}
}
Linklist* temp=p->next;
p->next=temp->next;
free(temp);
//更新结点中链表的长度
head->text.len++;
}
//遍历链表
void show_linklist(Linklist* head)
{
Linklist* p=head;
while(p->next != NULL)
{
p=p->next;
printf("%d\n",p->text.data);
}
putchar(10);
return;
}
int main(int argc, const char *argv[])
{
Linklist* head;
head=Create_Linklist();
insert_linkByIndex(head,100,1);
insert_linkByIndex(head,200,2);
insert_linkByIndex(head,300,3);
insert_linkByIndex(head,800,4);
del_linkByIndex(head,3);
// del_LinkByhead(head);
// del_LinkByhead(head);
// del_LinkBytail(head);
show_linklist(head);
return 0;
}
单向循环链表
#include <stdio.h>
#include <stdlib.h>
#include "./03_DoubleListFun.h"
//创建单链表
Doulist* Create_Doulist(void)
{
//在堆空间申请了头节点的空间,头节点的首地址存储在head指针中。
//head指针就是头指针
Doulist* head=(Doulist*)malloc(sizeof(Doulist));
if(NULL == head)
{
printf("单链表创见失败\n");
return NULL;
}
//初始化头节点中的len
head->next = head;
head->text.len=0;
return head;
}
//头插法
void insert_linkByHead(Doulist* head,int num)
{
//创建一个新的节点
Doulist* temp = (Doulist*)malloc(sizeof(Doulist));
temp->text.data=num;
temp->next=NULL;
//将temp头插法插入链表
temp->next = head->next;
head->next = temp;
//更新头节点中链表的长度
head->text.len++;
}
//尾插法
void insert_doulistByTail(Doulist* head,typedata num)
{
//创建新的节点
Doulist* temp=(Doulist*)malloc(sizeof(Doulist));
temp->text.data=num;
temp->next=head;
//找到节点p的位置:循环判断p->next是否为NULL
Doulist* p=head;
p=head;
while(p->next != head)
{
p=p->next;
}
//尾插法插入数据
temp->next=p->next;
p->next=temp;
//更新结点中链表的长度
head->text.len++;
}
//头删法
void del_DouByhead(Doulist* head)
{
Doulist* temp= (Doulist*)malloc(sizeof(Doulist));
//判断链表是否为空
if(head->next == head)
{
printf("链表为空删除失败\n");
return;
}
//将要释放的节点地址另存
temp=head->next;
head->next=temp->next;
//释放结点
free(temp);
temp=NULL;
//更新头结点链表长度
head->text.len--;
}
//尾删法
void del_DouBytail(Doulist* head)
{
Doulist* p=head;
//判断链表是否为空
if(head->next == head)
{
printf("链表为空删除失败\n");
return;
}
//循环方式找倒数2个结点p
while(p->next->next != head)
{
p=p->next;
}
Doulist* temp;
temp=p->next;
p->next=temp->next;
//释放结点
free(temp);
//更新头结点链表长度
head->text.len--;
}
//按位置插入
void insert_DoulistByIndex(Doulist* head,typedata num,int n)
{
//判断插入位置是否合法
if(n<1)
{
printf("n=%d插入位置非法\n",n);
return;
}
//找要插入的位置的前一个节点位置
//若p指向NULL,则代表插入位置非法
Doulist* p = head;
for(int i=0;i<n-1;i++)
{
p=p->next;
if(head == p->next)
{
printf("n=%d插入位置非法\n",n);
return;
}
}
//创建一个新的节点
Doulist* temp=(Doulist*)malloc(sizeof(Doulist));
if(NULL == temp)
{
printf("创建结点失败,插入失败\n");
return;
}
temp->text.data=num;
temp->next = NULL;
//将temp插入到p结点的后一个位置
temp->next=p->next;
p->next=temp;
//更新头结点中链表的长度
head->text.len++;
return;
}
//按位置删除
void del_doulistByIndex(Doulist* head,int n)
{
//判断链表是否为空
if(head == head->next)
{
printf("链表为空,按位置删除失败\n");
return;
}
//判断删除位置是否合法
if(n<1)
{
printf("n=%d删除位置非法\n",n);
return;
}
//找到要删除位置的前一个结点位置
Doulist* p = head;
for(int i=0;i<n-1;i++)
{
p=p->next;
if(p->next == head)
{
printf("n=%d删除非法\n",n);
return;
}
}
Doulist* temp=p->next;
p->next=temp->next;
free(temp);
//更新结点中链表的长度
head->text.len++;
}
//直接插入排序
void insert_linkSort(Doulist* head,typedata num)
{
//创建一个新的节点
Doulist* temp=(Doulist*)malloc(sizeof(Doulist));
if(NULL == temp)
{
printf("创建结点失败,直接插入排序失败\n");
return;
}
temp->text.data=num;
temp->next = NULL;
//找到要插入位置的前一个结点位置:
//当前结点的下一个结点是否大于要插入的数据num
Doulist* p,*q;
p=head;
while(p->next!=NULL)
{
if(num<p->next->text.data)
{
break;
}
p=p->next;
}
//将temp插入到p结点后面位置
temp->next=p->next;
p->next=temp;
//更新头结点中链表的长度
head->text.len++;
}
//链表翻转
void trainsform_list(Doulist* head)
{
Doulist* p,*q;
p=head->next;
head->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=head->next;
head->next=p;
p=q;
}
printf("链表翻转完成\n");
}
//找中间结点:快慢指针
typedata moidNode(Doulist* head)
{
//判断链表是否为空
if(NULL == head->next)
{
printf("链表为空,没有中间结点\n");
return (typedata)-1;
}
Doulist*fast,*low;
fast=low=head->next;
while(fast!=NULL && fast->next!=NULL)
{
low=low->next;
fast=fast->next->next;
}
return low->text.data;
}
//释放链表
void free_linklist(Doulist** phead)
{
//phead指向head空间
//*phead代表访问head空间
Doulist* temp = NULL;
//循环头删,直到链表为空
while((*phead)->next != NULL)
{
temp = (*phead)->next;
(*phead)->next = temp->next;
free(temp);
(*phead)->text.len--;
}
//最后释放头结点,将头指针置为NULL
free(*phead);
*phead = NULL;
return;
}
//遍历链表
void show_doulinklist(Doulist* head)
{
Doulist* p=head;
while(p->next != head)
{
p=p->next;
printf("%d\n",p->text.data);
}
putchar(10);
return;
}