main函数
#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; }
头文件:
#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
函数部分:
#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:
-include ./makefile.cfg $(Target):$(Obj)$(CC) $^ -o $@%.o:%.c$(CC) $< $(CAN) $@.PHONY: cleanclean:rm $(Obj)
makefile.cfg
Target:=a.out
Obj:=01_main.o 02_linkList.o
CAN:= -c -o
CC:=gcc