接上篇顺序表,这篇写的是带头节点的单链表
# include "stdlib.h"
# include "stdio.h"
# define OK 1
# define ERROR 0
typedef int Status;//自定义数据类型 相当于int仅用作装逼
//实现一个带头节点的单链表
//节点类
typedef struct LNode{
int data;//传说中的数据域 结构体A.next 指针 A->next
struct LNode *next;//传说中的指针域
}LNode;
//头插法建立单链表
LNode* headInitList(int A[]){
/**在函数中获取传入的数组的实际长度的奇技淫巧。。。
* 方法一,长得丑了点,但是很好理解,而且可以判断空的数组,不用减
* int len;
* for (int i = 0; *(A+i) != '\0'; ){
* i++;
* len = i;
* };
* 方法二,忘记了在哪里看到了学来的
* ++len 没有判断A[0]的值,不适用于空的数组 意思是先自加再应用到A+len
* len++ 可以判断A[0]是否为空,可用于空的数组,要在最后结束了让len-1才是真实的数组长度
*
* 如果传入了一个空的数组,那就只返回一个头结点就好了
*/
int len = 0;
while(*(A+(len++))!='\0');
len--;
LNode *head = (LNode*)malloc(sizeof(LNode));
/*这里一定要记得将头结点的next置空*/
head->next = NULL;
for (int i = len; i > 0; i--)
{
LNode *new = (LNode*)malloc(sizeof(LNode));
new->next = head->next;
new->data = A[i-1];
head->next = new;
}
printf("头插法建立单链表成功\n");
return head;
}
//尾插法建立单链表
LNode* tailInitList(int A[]){
int len = 0;
while(*(A+(len++))!='\0');
len--;
LNode *head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
LNode *tail = head;
for (int i = 0; i < len; i++)
{
LNode *new = (LNode*)malloc(sizeof(LNode));
new->data = A[i];
new->next = NULL;
tail->next = new;
tail = tail->next;
}
printf("尾插法建立单链表成功\n");
return head;
}
//初始化一个单链表,返回头结点
LNode* InitList(){
LNode *head = (LNode*)malloc(sizeof(LNode));
if(head){
head->next = NULL;
printf("单链表初始化成功\n");
return head;
}
}
//按位取元素
Status GetElem(LNode *L ,int n){
int i = 0;
LNode *p = L;
while (p->next){
p = p->next;
i++;
if (i == n)
{
printf("单链表中第%d个元素中data=%d\n",n,p->data);
return OK;
}
}
printf("当前单链表中共有%d个元素,你输入的数值%d错误\n",i,n);
return ERROR;
}
// //查找元素
Status LocateElem(LNode *L, int e){
int i = 0;
LNode *p = L;
while (p->next){
p = p->next;
i++;
if(p->data== e){
printf("你要查找的元素位于单链表中第%d位\n",i);
return OK;
}
}
printf("你要查找的元素不存在\n");
return ERROR;
}
// 插入元素
Status ListInsert(LNode *L, int n, int e){
LNode *p =L;
int i = 0;
while (p->next)
{
p = p->next;
i++;
if (n == i)
{
LNode *q = (LNode*)malloc(sizeof(LNode));
q->data = e;
q->next = p->next;
p->next = q;
printf("元素插入成功");
return OK;
}
}
if (n == i+1){
LNode *q = (LNode*)malloc(sizeof(LNode));
q->data = e;
q->next = p->next;
p->next = q;
printf("元素插入成功\n");
return OK;
}
printf("元素插入失败,当前共有%d个元素,你想插入的位置%d不正确\n",i,n);
}
// //删除元素
Status ListDelete(LNode *L, int n){
int i = 0;
LNode *p = L;
LNode *temp;
while (p->next)
{
i++;
if (n==i)
{
temp = p->next;
p->next = temp->next;
free(temp);
printf("删除元素%d成功\n", i);
return OK;
}
p = p->next;
}
printf("当前单链表共%d个元素,你想删除的元素%d不存在\n",i,n);
return ERROR;
}
//遍历单链表
Status ListPrint(LNode *L){
LNode *p = L;
while (p->next)
{
p = p->next;
printf("data:%d\n",p->data);
}
return OK;
}
// //查看表长
Status ListLength(LNode *L){
int i = 0;
LNode *p = L;
while (p->next)
{
p = p->next;
i++;
}
printf("单链表的长度是%d\n",i);
return OK;
}
// //清空单链表
Status ListClear(LNode *L){
LNode *temp;
LNode *p = L;
while (p->next)
{
temp = p->next;
p->next = temp->next;
free(temp);
}
printf("单链表已经清空\n");
return OK;
}
// //判断单链表是否为空
Status ListEmpty(LNode *L){
LNode *p = L;
if (p->next)
{
printf("单链表不为空\n");
return ERROR;
}
printf("单链表为空\n");
return OK;
}
//销毁单链表
Status ListDestroy(LNode *L){
ListClear(L);
free(L);
printf("单链表已销毁");
return OK;
}
int main(int argc, char const *argv[])
{
// LNode *L = InitList();
// ListInsert(L,1,1);
// ListInsert(L,2,2);
// ListInsert(L,2,3);
// ListInsert(L,5,3);
// ListDelete(L,1);
// ListPrint(L);
// ListLength(L);
// ListEmpty(L);
// ListClear(L);
// ListEmpty(L);
// ListLength(L);
// ListDestroy(L);
//测试头插法建立单链表
// int A[6] = {1,2,3,4,5}; //这里故意就弄五个只为了测试上面的数组长度算法
// LNode *L = headInitList(A);
// ListPrint(L);
//测试尾插法建立单链表
int A[6] = {1,2,3,4,5};
LNode *L = tailInitList(A);
ListPrint(L);
}