当我们用数组存储数据的时候 ,不能更好的对内存实现掌握,连续的大开小用,消耗太大,因此动态的申请空间,达到对内存的合理使用,因此链式存储,在实际使用中就显得尤为重要,而链表中既要有存储数据的数据域,也要有指向下一个节点的node 的指针,这样才能将所有的节点连起来。如下图
每一个节点中都有一个数据和指向下一个节点的指针 为了方便跟好的操作第一个节点因此加入一个头节点 head 指向第一个节点 在最后一个节点的指针域赋值为NULL
因此,单链表的结构体为
typedef int ElemType; // data 数据类型 typedef struct ListNode { ElemType data; // 数据域 ListNode *next; // 指针域 }ListNode; typedef struct { ListNode *head; // 头节点 指向第一个节点 int cursize; // 记录节点个数 }List;
对单链表实现已下功能
ListNode * Buynode(); // 购买一个节点 void Freenode(ListNode *p); // 销毁节点 void InitList(List &mylist); // 初始化节点 void Insert_Item(List &mylist,int pos,ElemType val);// 往节点中插入数据 void push_back(List &mylist,ElemType val);// 尾插 void push_front(List &mylist,ElemType val);// 头插 void Insert_fill_n(List &mylist,unsigned int size,ElemType val);// 插入size个数据 void Insert_Ar(List &mylist,ElemType *_F,ElemType *_L); // 将数组元素插入链表 ListNode * FindValue(List &mylist,ElemType val); // 按值查找返回节点地址 ListNode * FindPreValue(List &mylist,ElemType val); // 按值查找返回节点前驱地址 ListNode * FindPos(List &mylist,int pos); // 按位置查找返回节点地址 ListNode * FindPrePos(List &mylist,int pos); // 按位置查找返回节点前驱地址 void Erase(List &mylist,int pos); // 删除pos 位置上的值 void pop_back(List &mylist); // 尾部删除 void pop_front(List &mylist); // 头部删除 void remove(List &mylist,ElemType val); // 按值删除第一个 void remove_all(List &mylist,ElemType val); // 按值删除所有 void ReversList(List &mylist); // 链表逆置 bool MergrList(List &mylist,List &helist,List &sheliet); // 按数据大小合并两条链表
#include<stdio.h> #include<malloc.h> #include<iostream> #include<stdlib.h> #include<string.h> #include<assert.h> typedef int ElemType; typedef struct ListNode { ElemType data; ListNode *next; }ListNode; typedef struct { ListNode *head; int cursize; }List; ListNode * Buynode() { ListNode *s =(ListNode*)malloc(sizeof(ListNode)); if(NULL == s) exit(1); memset(s,0,sizeof(ListNode)); return s; } void Freenode(ListNode *p) { free(p); } void InitList(List &mylist) { mylist.head = Buynode(); // head; mylist.cursize = 0; } void Insert_Item(List &mylist,int pos,ElemType val) { if(pos <= 0 || pos > mylist.cursize +1) return ; ListNode *p = mylist.head; int i = 1; while(i<pos) { p = p->next; ++i;} ListNode *s = Buynode(); s->data = val; s->next = p->next; p->next = s; mylist.cursize+=1; } void push_back(List &mylist,ElemType val) { Insert_Item(mylist,mylist.cursize+1,val); } void push_front(List &mylist,ElemType val) { Insert_Item(mylist,1,val); } void Insert_fill_n(List &mylist,unsigned int size,ElemType val) { while(size--) { push_back(mylist,val); } } void Insert_Ar(List &mylist,ElemType *_F,ElemType *_L) { assert(_F != NULL && _L != NULL); for(; _F != _L; ++_F) { push_back(mylist,*_F); } } ListNode * FindValue(List &mylist,ElemType val) { ListNode * p = mylist.head->next; while(p != NULL && p->data != val) { p = p->next; } return p; } ListNode * FindPreValue(List &mylist,ElemType val) { ListNode *p = mylist.head; while(p != NULL && p->next != NULL && p->next->data != val) { p = p->next; } if(p->next == NULL) { p = NULL; } return p; }ListNode * FindPos(List &mylist,int pos) { if(pos < 1 || pos > mylist.cursize) return NULL; ListNode * p = mylist.head->next; int i = 1; while(i<pos) { p = p->next; ++i; } return p; } ListNode * FindPrePos(List &mylist,int pos) { if(pos < 1 || pos > mylist.cursize) return NULL; ListNode * p = mylist.head; int i = 1; while(i<pos) { p = p->next; ++i; } return p; } void Erase(List &mylist,int pos) { ListNode *p = FindPrePos(mylist,pos); if(NULL == p) return ; ListNode *q = p->next; p->next = q->next; Freenode(q); mylist.cursize -=1; } void pop_back(List &mylist) { Erase(mylist,mylist.cursize); } void pop_front(List &mylist) { Erase(mylist,1); } void remove(List &mylist,ElemType val) { ListNode *p = FindPreValue(mylist,val); if(NULL == p) return ; ListNode *q = p->next; p->next = q->next; Freenode(q); mylist.cursize -=1; } void remove_all(List &mylist,ElemType val) { ListNode *p = mylist.head; while(p != NULL && p->next != NULL) { if(p->next->data == val) { ListNode *q = p->next; p->next = q->next; Freenode(q); mylist.cursize-=1; } else { p = p->next; } } } void ReversList(List &mylist) { if(mylist.cursize < 2) return ; ListNode *p = mylist.head->next; mylist.head->next = NULL; while(p != NULL) { ListNode *s = p; p = p->next; s->next = mylist.head->next; mylist.head->next = s; } }