main函数
cpp#include <stdio.h> #include "./03_linkList.h" int main(int argc, const char *argv[]) { linkList* head = creatr_linkList(); insertHead_linkList(head,37); insertHead_linkList(head,35); insertHead_linkList(head,28); insertHead_linkList(head,13); show_linkList(head); insertSort_linkList(head,23); show_linkList(head); selectByposition(head,3); return 0; }
头文件:
cpp
#ifndef __linkList_H__
#define __linkList_H__
typedef int datatype;
union msg{ //若数据的类型也为int,则不需要这个联合体
datatype data;
int len; //放头结点,记录链表长度
};
typedef struct node{
union msg text;
struct node* next; //指针,由于指针指向这一整个节点,所以类型为struct node*
}linkList;
linkList* creatr_linkList(void);
void insertHead_linkList(linkList* head,datatype num);
void show_linkList(linkList* head);
void insertTail_linkList(linkList* head,datatype num);
void deleteHead_linkList(linkList* head);
void deleteTail_linkList(linkList* head);
void insertByPositon_linkList(linkList* head,int pos,datatype num);
void deleteByposition_linkList(linkList* head,int pos);
void selectByposition(linkList* head,int pos);
void insertSort_linkList(linkList* head,datatype num);
#endif
函数部分:
cpp
#include <stdio.h>
#include <stdlib.h>
#include "./03_linkList.h"
//创建一个带有头指针的单向空链表
linkList* creatr_linkList()
{
linkList* head = (linkList*)malloc(sizeof(linkList));
if(NULL == head)
{
printf("头结点申请失败!\n");
return NULL;
}
head->text.len = 0;//将链表长度初始化为0
head->next = NULL;//第一个结点的指针指向空
return head;
}
//判断链表是否为空
int isEmpty_linkList(linkList* head)
{
return head->next==NULL ? 1:0;
}
//插入数据
//头插法
void insertHead_linkList(linkList* head,datatype num)
{
//创建一个新的结点
linkList* temp =(linkList*)malloc(sizeof(linkList));
if(NULL==temp)
{
printf("结点申请失败!\n");
return;
}
//定义该节点
temp->text.data=num;//将需要插入的数据赋值给该结点
temp->next=NULL;//先将插入的结点指向空
//先将temp指针指向头指针原先指向的那个元素,然后将头指针重新指向temp
temp->next=head->next;
head->next=temp;
//插入了新的元素,链表长度增加
head->text.len++;
return;
}
//尾插
void insertTail_linkList(linkList* head,datatype num)
{
//创建一个新的结点
linkList* temp =(linkList*)malloc(sizeof(linkList));
if(NULL==temp)
{
printf("结点申请失败!\n");
return;
}
//定义该节点
temp->text.data=num;//将需要插入的数据赋值给该结点
temp->next=NULL;//先将插入的结点指向空
linkList* p=head;//定义一个p找到链表的尾部
while(p->next!=NULL)
{
p=p->next;
}
//当p->next==NULL时退出循环,此时就是链表的尾部
p->next=temp;//直接将尾部指向temp
temp->next=NULL;//然后将temp->next指向空
head->text.len++;
return;
}
//头删
void deleteHead_linkList(linkList* head)
{
if(isEmpty_linkList(head))
{
printf("该链表为空,删除失败!\n");
return;
}
linkList* temp=head->next;
head->next=temp->next;
free(temp);
temp=NULL;
head->text.len--;
return;
}
//尾删
void deleteTail_linkList(linkList* head)
{
if(isEmpty_linkList(head))
{
printf("该链表为空,删除失败!\n");
return;
}
linkList* temp=head;
while(temp->next->next!=NULL)
{
temp=temp->next;
}
free(temp->next);
temp->next=NULL;
head->text.len--;
return;
}
//按位置插入,位置编号从1开始编号
void insertByPositon_linkList(linkList* head,int pos,datatype num)
{
//判断插入的位置是否合法
if(pos < 1 || pos >head->text.len+1)
{
printf("插入的位置非法!\n");
return;
}
linkList* p=head;
int i=0;
//利用for循环找到目标位置的前一个结点
for(i=0;i<pos-1;i++)
{
p=p->next;
}
linkList* temp=(linkList*)malloc(sizeof(linkList));
if(NULL==temp)
{
printf("结点申请失败!\n");
return;
}
//定义该节点
temp->text.data=num;//将需要插入的数据赋值给该结点
temp->next=NULL;//先将插入的结点指向空
//插入操作
temp->next=p->next;
p->next=temp;
head->text.len++;
return;
}
//按位置删除
void deleteByposition_linkList(linkList* head,int pos)
{
if(isEmpty_linkList(head))
{
printf("该链表为空,删除失败!\n");
return;
}
if(pos < 1 || pos >head->text.len)
{
printf("删除的位置非法!\n");
return;
}
linkList* p=head;
int i;
for(i=0;i<pos-1;i++)//找到需要删除位置的前一个结点
{
p=p->next;
}
linkList* temp=p->next;
p->next=p->next->next;
free(temp);
temp=NULL;
head->text.len--;
return;
}
//按位置查找数据,从11开始
void selectByposition(linkList* head,int pos)
{
if(isEmpty_linkList(head))
{
printf("该链表为空,查找失败!\n");
return;
}
if(pos < 1 || pos >head->text.len)
{
printf("查找的位置非法!\n");
return;
}
int i;
linkList* p=head;
for(i=0;i<pos;i++)//找到需要查找的结点的位置
{
p=p->next;
}
printf("%d位置的数据是%d\n",pos,p->text.data);
return;
}
//直接插入排序
void insertSort_linkList(linkList* head,datatype num)
{
linkList* p = head;//用于找到比temp大的前一个数的结点
linkList* temp=(linkList*)malloc(sizeof(linkList));
if(NULL==temp)
{
printf("结点申请失败!\n");
return;
}
//定义该节点
temp->text.data=num;//将需要插入的数据赋值给该结点
temp->next=NULL;//先将插入的结点指向空
//当p->next为空时,即在尾部插入,此时p不需要再偏移了,
//如果temp插入位置
while(p->next!=NULL && p->next->text.data < temp->text.data)
{
p=p->next;
}
temp->next=p->next;
p->next=temp;
head->text.len++;
return;
}
//遍历该链表
void show_linkList(linkList* head)
{
//定义一个指针指向该链表的头结点,然后将p后移访问该链表中的数据
linkList* p=head;
while(p->next!=NULL)
{
p=p->next;//将p后移,由于p刚开始指向的是head,不是有效数据,所以先后移再访问数据
printf("%d ",p->text.data);//打印p所指向的数据
}
printf("\n");
}
Makefile:
cpp
-include ./makefile.cfg
$(Target):$(Obj)
$(CC) $^ -o $@
%.o:%.c
$(CC) $< $(CAN) $@
.PHONY: clean
clean:
rm $(Obj)
makefile.cfg
cpp
Target:=a.out
Obj:=01_main.o 02_linkList.o
CAN:= -c -o
CC:=gcc