p79-85

该文本展示了一系列SQL命令,包括在student1表中创建、插入、查询、更新和删除学生记录,以及使用replaceintotable、setsql_safe_updates和truncatetable等特殊操作。内容涉及学生的学号、姓名、性别、出生日期和成绩等信息。

 

use stusys;
desc student;
create table student1 like student;
desc student1;
insert into student1
 values
  ('196001','董明霞','女','1999-05-02','通信',50);
select *from student1;
insert into student1 (sno,sname,speciality,tc,ssex,sbirthdat)
 values
  ('196002','李茜','通信','48','女','1998-07-25');
select *from student1;
insert into student1 (sno,sname,sbirthdat,tc)
 values
  ('196004','周俊文','1998-03-10',52);

select *from student;
replace into student1
 values
  ('196002','李茜','女','1998-07-25','通信',48);
create table student2 like student;
insert into student2
select *from student;
select *from student2;

use stusys;
set sql_safe_updates=0;
update student1
set sbirthdat ='1999-03-10'
    where sname ='周俊文';
select *from student1;
select *from student;
update student1
 set tc = tc+2;
select *from student1;
delete from student1
 where sno='196004';
delete from student1;
truncate student;
select *from student;

你的 `link_insert()` 函数的目的是**在指定位置插入一个新节点**。从代码结构来看,你使用的是**双向链表(doubly linked list)结构**,即每个节点都有 `next` 和 `prior` 指针。 但你当前的实现中存在一些**逻辑错误和可能导致段错误的问题**,我们来逐行分析并给出修正方案。 --- ## ✅ 1. 结构体定义(假设) 你使用的结构体如下: ```c typedef struct Node { data_t data; struct Node *next; struct Node *prior; } link_t; ``` 这说明你操作的是**双向链表**,插入节点时必须同时维护 `next` 和 `prior` 指针。 --- ## ❌ 2. 存在的问题分析 ### 🔴 问题 1:插入位置越界判断错误 ```c if(pos<0 || pos >get_length(head)) ``` - **错误点**:`pos > get_length(head)` 应该是 `pos > get_length(head)` 的节点插入是**非法的**。 - **正确逻辑**:插入位置可以是 `0 ~ get_length(head)`,即允许在链表尾部插入。 - ✅ **应改为**: ```c if(pos < 0 || pos > get_length(head)) return -1; ``` --- ### 🔴 问题 2:插入逻辑混乱 ```c if(head->next == NULL) { p->next = new; new->next = p; new->next = NULL; } ``` 这段代码逻辑错误: - `new->next = p;` 然后又 `new->next = NULL;`,这是**多余且矛盾**的赋值; - 你试图处理空链表的情况,但逻辑混乱; - ✅ **正确做法是**:当 `p` 是最后一个节点时,直接插入到 `p->next`。 --- ### 🔴 问题 3:插入逻辑不统一 你将插入分为两种情况处理: ```c if (head->next == NULL) else ``` 但**这并不等于链表为空**,只是表示头节点的 `next` 为空。 你真正要判断的是: ```c if (p->next == NULL) ``` 即是否在链表末尾插入。 --- ### 🔴 问题 4:双向链表指针维护不完整 你维护了 `prior` 指针,但未完全正确处理双向链接: ```c p->next->prior = new; new->next = p->next; p->next = new; new->prior = p; ``` 这部分是**标准的双向链表插入逻辑**,但在其他分支中没有统一维护。 --- ## ✅ 正确插入逻辑(标准双向链表插入) 我们来提供一个**统一、安全、清晰的双向链表插入逻辑**: ```c int link_insert(link_t *head, int pos, data_t x) { if (pos < 0 || pos > get_length(head)) return -1; link_t *p = head; while (pos--) { p = p->next; } link_t *new = (link_t *)malloc(sizeof(link_t)); if (new == NULL) return -1; new->data = x; // 双向链表的标准插入方式 new->next = p->next; new->prior = p; if (p->next != NULL) p->next->prior = new; p->next = new; return 0; } ``` --- ## 📊 插入过程图解(插入到 pos = 2) 原始链表: ``` head ↔ A ↔ B ↔ C ↔ NULL ``` 插入新节点 `X` 到位置 2: ``` head ↔ A ↔ B ↔ X ↔ C ↔ NULL ``` - `X->next = B->next = C` - `X->prior = B` - `C->prior = X` - `B->next = X` --- ## 📌 总结:你代码中的问题 | 问题 | 错误描述 | 建议 | |------|----------|------| | 1 | `pos` 判断错误 | 插入位置应允许 `0 ~ get_length(head)` | | 2 | 插入逻辑混乱 | 统一使用标准双向链表插入逻辑 | | 3 | 多余赋值 `new->next` | 删除无效赋值 | | 4 | 条件判断错误 | 判断 `p->next == NULL` 而不是 `head->next == NULL` | --- ## ✅ 正确写法总结 ```c int link_insert(link_t *head, int pos, data_t x) { if (pos < 0 || pos > get_length(head)) return -1; link_t *p = head; while (pos--) { p = p->next; } link_t *new = (link_t *)malloc(sizeof(link_t)); if (new == NULL) return -1; new->data = x; new->next = p->next; new->prior = p; if (p->next != NULL) p->next->prior = new; p->next = new; return 0; } ``` --- ## 📚 知识点总结 - **双向链表插入逻辑**:插入新节点时需要维护 `next` 和 `prior` 两个方向的指针。 - **边界条件检查**:确保 `pos` 在合法范围内,防止越界访问。 - **动态内存安全操作**:每次使用 `malloc()` 后都要检查是否成功分配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ALhq1008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值