typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList;

带头结点的按位序插入:

//在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, char e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
} if (p == NULL) //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode)); //新结点
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

不带头结点的按位序插入:(对于插入第一个结点时需要特殊处理,其他部分与带头结点的一样)

bool ListInsert(LinkList &L, int i, char e) {
if (i == ) {
LNode *s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true
}
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
} if (p == NULL) //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode)); //新结点
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

指定结点的后插操作:

//在p结点之后插入元素e
bool InsertNextNode(LNode *p, char e) {
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
return false; //内存分配失败
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

这里的后插操作其实就相当于已经找到了p,和按位序插入while循环后边的代码一样了,所以按位序插入后边部分可以调用这个函数:

//在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, char e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
}
  return InsertNextNode(p,e)
}

指定结点的前插操作:

如果给了头指针的话,只需要循环查找到要插入结点的前一个结点,然后插入即可

//在p结点之前插入元素e
bool InsertPriorNode(LinkList L, LNode *p, char e)

然而如果不给头指针的话,就需要偷天换日一下,把新结点插入到p结点后边,然后把新结点的数据元素和和p结点互换,逻辑上实现同样的效果

//在p结点之前插入元素e
bool InsertPriorNode(LNode *p, char e) {
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
return false; //内存分配失败
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return true;
}

如果是直接传入了结点s,道理是一样的;

//在p结点之前插入结点s
bool InsertPriorNode(LNode *p, LNode *s) {
if (p == NULL || s == NULL)
return false;
s->next = p->next;
p->next = s;
char temp = p->data;
p->data = s->data;
s->data = temp;
return true;
}

按位序删除(带头结点):

前半部分与插入结点一样,先循环查找p

//删除表L中第i个位置的元素,并用e返回删除元素的值
bool ListDelete(LinkList &L, int i, char &e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) {
p = p->next;
j++;
} if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode *q = p->next; //令q指向被删除的结点
e = q->data; //用e返回被删的值
p->next = q->next; //断开连接
free(q); //释放被删结点空间
return true;
}

指定结点的删除:

删除结点p,需要修改其前驱 结点的next指针
方法1:传入头指针,循环寻找p的前驱结点

方法2:偷天换日(类似于结点前插的实现)

下面是方法2的代码实现:

//删除指定结点p
bool DeleteNode(LNode *p) {
if (p == NULL)
return false;
LNode *q = p->next; //令q指向*p的后继结点
p->data = p->next->data;
p->next = q->next;
free(q);
return true;
}

如果p是最后一个结点就只能从表头开始依次寻找p的前驱...

最新文章

  1. 图片根据需要突出div
  2. extjs学习(关于grid)
  3. yii2增加验证码详细步骤
  4. javascrit2.0完全参考手册(第二版) 第1章第1节 在XHTML文档中增加javascript
  5. 求二叉树的深度和宽度[Java]
  6. 【体系结构】Oracle参数介绍
  7. Android WebView使用基础
  8. [terry笔记]Flashback
  9. ListView(3)关于listview滚动事件,何时滚动到顶部或底部
  10. MenuItem
  11. centos git gitolite安装笔记
  12. js拖动层
  13. 足球和oracle系列(3):oracle过程排名,世界杯第二回合战罢到来!
  14. UltraEdit激活方法
  15. day 8 - 2 文件操作练习
  16. IDEA乱码解决
  17. C# 中使用面向切面编程(AOP)中实践代码整洁(转)
  18. Sorted方法排序用法
  19. 10.14 (上午)开课一个月零十天 (PHP环境搭建)
  20. Lwip:原生态的Linux socket应用如何移植到Lwip上

热门文章

  1. poj2914无向图的最小割
  2. vue脚手架3.0的安装与使用
  3. Kubernetes as Database: 使用kubesql查询kubernetes资源
  4. Java——java.lang.NumberFormatException: For input string: &quot;&quot;
  5. web自动化之Select标签操作
  6. Golang源码学习:调度逻辑(三)工作线程的执行流程与调度循环
  7. 【JavaScript数据结构系列】04-优先队列PriorityQueue
  8. Ant标签详解--基础操作
  9. 函数:exit()
  10. [Objective-C] 011_数据持久化_NSKeyedArchiver