# 单链表基础

### 创建一个单链表

typedef struct LNode {
ElemType data; //数据域
struct LNode *next; //指针域
}LNode, *LinkList;

### 头插法

void CreatList1(LinkList &L, int n) {  //头插法
LNode *p;
for(int i = 0; i < n; ++i) {
p = (LNode*)malloc(sizeof(LNode));
p->data = i;
p->next = L->next;
L->next = p;
}
}

### 尾插法

void CreatList2(LinkList &L, int n) { //尾插法
LNode *p, *q;
p = L;
for(int i = 0; i < n; ++i) {
q = (LNode*)malloc(sizeof(LNode));
q->data = i;
q->next = NULL;
p->next = q;
p = q;
}
}

### 循秩查找

LNode *GetEelm(LinkList L, int i) { //返回单链表第i个位置上结点（循秩查找）
int j = 1;  //计数器，初始值为1
LNode *p = L->next;
if(i == 0) return L; //返回头结点
if(i < 0) return NULL; //不存在该节点
while(p && j < i) {
p = p->next;
j++;
}
return p;
}

### 按值查找

LNode *LocateElem(LinkList L, ElemType e)   //按值查找结点
{
LNode *p = L->next;
while(p != NULL && p.data != e) p = p->next;
return p;
}

### 插入节点

bool InsertLNode(LinkList &L, int i, Elemtype)
{
if(i <= 0) return false;
LNode *p = GetEelm(L, i - 1);
if(!p) return false;
LNode *q = (LNode*)malloc(sizeof(LNode));
q->next = p->next;
p->next = q;
return true;
}

s->next = p->next;
p->next = s;
//交换数据域
temp = p->next;
p->data = s->data;
s->data = temp;

### 删除结点操作

bool DeleteLNode(LinkList &L, int i, ElemType)
{
if(i <= 0) return false;
LNode *p = GetEelm(L, i - 1);
if(!p) return false;
LNode *q = p->next;
p->next = q->next;
free(q);
return true;
}

### 求单链表表长

$O(n)$

int LinkListLength(LinkList L)
{
int cnt = 0;
LNode *p = L->next;
while(p){
cnt++;
p = p->next;
}
return cnt;
}

### 单链表的逆置

#### 头插法

void reverse1(LinkList &L)
{
LNode *p, *q;
*p = L->next;
L->next = NULL;
while(p) {
q = p;
p = p->next;
p->next = L->next;
L->next = p;
}
}

#### 就地逆置法

(1)非递归法：

void reverse1(LinkList &L)  //传入头结点的写法
{
LNode *p, *q;
p = L->next;
L->next = NULL;
while(p) {
q = p;
p = p->next;
q->next = L->next;
L->next = q;
}
}


(2)递归法：

LNode *reverse2(LinkList &head)  //传入头指针的写法
{
}