2017-4-15

tarjan算法模版

#include<iostream>  

using namespace std;  
int DFN[105];                                  //记录在做dfs时节点的搜索次序  
int low[105];                                  //记录节点能够找到的最先访问的祖先的记号  
int count=1;                                   //标记访问次序,时间戳  
int stack[105];                                //压入栈中  
int top=-1;  
int flag[105];                                 //标记节点是否已经在栈中  
int number=0;  
int j;  
int matrix[105][105]={{0,1,1,0,0,0},{0,0,0,1,0,0},{0,0,0,1,1,0},{1,0,0,0,0,1},{0,0,0,0,0,1},{0,0,0,0,0,0}};  
int length;                                    //图的长度  
void tarjan(int u){  
    DFN[u]=low[u]=count++;                     //初始化两个值,自己为能找到的最先访问的祖先  
    stack[++top]=u;  
    flag[u]=1;                                 //标记为已经在栈中  
  
    for(int v=0;v<length;v++){  
    if(matrix[u][v]){  
        if(!DFN[v]){                       //如果点i没有被访问过  
        tarjan(v);                     //递归访问  
        if(low[v]<low[u])  
            low[u]=low[v];             //更新能找的到祖先  
        }  
        else{                              //如果访问过了,并且该点的DFN更小,则  
        if(DFN[v]<low[u]&&flag[v])     //flag[v]这个判断条件很重要,这样可以避免已经确定在其他联通图的v,因为u到v的单向边而影响到u的low  
        low[u]=DFN[v];                 //也就是已经确定了的联通图要剔除掉,剔除的办法就是判断其还在栈中,因为已经确定了的连通图的点  
        }                                  //flag在下面的do while中已经设为0了(即已经从栈中剔除了)  
    }  
    }  
  
    //往后回溯的时候,如果发现DFN和low相同的节点,就可以把这个节点之后的节点全部弹栈,构成连通图  
    if(DFN[u]==low[u]){  
    number++;                               //记录连通图的数量  
    do{  
        j=stack[top--];                     //依次取出,直到u  
        cout<<j<<" ";  
        flag[j]=0;                          //设置为不在栈中  
    }while(j!=u);  
        cout<<endl;  
    }  
}  
int main(){  
      
    memset(DFN,0,sizeof(DFN));                  //数据的初始化  
    memset(low,0,sizeof(low));  
    memset(flag,0,sizeof(flag));  
      
    length=6;  
    tarjan(0);  
  
    cout<<endl;  
    for(int i=0;i<6;i++){  
    cout<<"DFN["<<i<<"]:"<<DFN[i]<<" low["<<i<<"]:"<<low[i]<<endl;  
    }  
    return 0;  

不是很好看,慢慢写


然后就是下午打算做一套模拟题,至少100吧。。。

————————————————————————————————————————————————————————————————————————————

``` CREATE TABLE t_product_category ( id int(20) NOT NULL COMMENT '主键', parent_id bigint(20) DEFAULT NULL COMMENT '父分类id', name varchar(150) DEFAULT NULL COMMENT '名称', status int(1) DEFAULT '1' COMMENT '状态 1:正常 0:删除', sort_order int(4) DEFAULT NULL COMMENT '排序号', is_parent int(1) DEFAULT NULL COMMENT '是否是父分类 1:是 0:否', created_time datetime DEFAULT NULL COMMENT '创建时间', modified_time datetime DEFAULT NULL COMMENT '最后修改时间', created_user varchar(50) DEFAULT NULL COMMENT '创建人', modified_user varchar(50) DEFAULT NULL COMMENT '最后修改人', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; LOCK TABLES t_product_category WRITE; INSERT INTO t_product_category VALUES (1,0,'图书、音像',0,1,1,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(2,1,'电子书刊',1,1,1,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(3,2,'电子书',1,1,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(4,2,'网络原创',1,2,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(5,2,'数字杂志',1,3,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(6,2,'多媒体图书',1,4,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(7,1,'音像',1,2,1,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(8,7,'音乐',1,1,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin'),(9,7,'影视',1,2,0,'2017-10-25 15:00:55','2017-10-25 15:00:55','admin','admin')```这种结构的表做商品分类怎么分类
最新发布
03-26
<think>好的,我现在需要帮用户分析他们提供的SQL表结构,并解释如何利用这种结构进行商品分类。首先,我得仔细看一下这个表的结构和示例数据,理解各个字段的作用。 首先,用户提供的表是`t_product_category`,看起来是一个典型的树形结构分类表。字段包括`id`、`parent_id`、`name`等,还有状态、排序、是否是父分类等管理字段。接下来,我需要确定这种结构如何实现商品分类的层级管理。 第一个关键点是`parent_id`字段,它用来指向父分类的ID。比如,在示例数据中,ID为1的分类的`parent_id`是0,可能表示这是顶级分类。而ID为2的分类的`parent_id`是1,说明它是ID为1的子分类。这种设计允许无限层级的分类,常见于商品分类系统。 然后,`is_parent`字段的作用是什么?这个字段标识当前分类是否是父分类,即是否有子分类。例如,ID为1的分类`is_parent`是1,表示它有子分类,而ID为3的分类`is_parent`是0,说明它是叶子节点,没有子分类。这可能在查询时用来快速判断是否需要展开子分类,或者在用户界面上显示不同的图标。 接下来是`sort_order`字段,它决定了同一层级下分类的显示顺序。例如,在父分类ID为2的子分类中,电子书(ID3)的排序是1,网络原创(ID4)是2,这样在显示时会按照1、2、3的顺序排列。这个字段对于管理分类的展示顺序非常重要。 状态字段`status`用来控制分类是否可用,1正常,0删除。这样可以实现软删除,保留数据而不实际删除记录。`created_time`和`modified_time`记录创建和修改时间,`created_user`和`modified_user`记录操作人,这些都是常见的审计字段,用于追踪数据变更。 现在,用户的问题是如何利用这种结构进行商品分类。我需要解释这种层级结构如何组织,可能的应用场景,以及管理上的便利性。比如,顶级分类可以是图书、音像,其下分电子书刊和音像,电子书刊下又有电子书、网络原创等。这种结构适合需要多级分类的场景,比如电商网站的商品分类。 可能用户还关心查询方式,比如如何查询所有子分类,或者如何构建树形结构。这时候可能需要使用递归查询或者应用层处理。但用户提供的示例数据中,层级不深,可能他们目前的层级较少,不需要复杂的递归。不过,表结构本身支持多级,这是好的。 另外,需要注意`is_parent`字段的维护。当添加或删除子分类时,需要更新父分类的`is_parent`状态。例如,如果删除了某个父分类下的所有子分类,需要将它的`is_parent`设为0。这可能需要在应用逻辑中处理,或者通过触发器实现,但示例中没看到触发器,所以可能是在应用层维护。 还有,主键`id`是int(20),而`parent_id`是bigint(20),这可能存在数据类型不一致的问题,但实际使用中如果id不会超过bigint的范围,可能问题不大,不过理论上parent_id应该和id类型一致,避免外键约束问题。不过用户可能没有设置外键约束,所以这只是一个设计上的考虑点。 最后,用户可能需要知道这种结构的优缺点。优点是灵活,支持多级分类;缺点是在查询深层级或树形结构时需要递归,可能影响性能。但示例数据中的层级不深,所以性能问题可能不明显。如果层级很深,可以考虑使用闭包表等设计,但当前结构对于大多数情况已经足够。 总结来说,这个表结构通过parent_id实现层级分类,利用is_parent标识是否有子分类,sort_order控制顺序,状态字段管理可用性,适合需要多级分类的商品管理系统。</think>这个商品分类表采用**树形结构设计**,通过`parent_id`字段实现无限层级分类。以下是具体分类逻辑和使用方法的逐步分析: --- ### 一、表结构解析(核心字段) | 字段 | 说明 | |---------------|--------------------------------------------------------------------| | `id` | 分类唯一标识,如`1`表示"图书、音像" | | `parent_id` | 父分类ID,`0`表示顶级分类 | | `name` | 分类名称,如"电子书" | | `is_parent` | 是否为父分类(是否包含子分类),`1=是`,`0=否` | | `sort_order` | 同级分类的显示顺序,数值越小越靠前 | --- ### 二、分类逻辑详解 #### 步骤1 - 构建层级关系 通过`parent_id`字段逐级关联: ``` 层级0(顶级): 1-图书、音像 (parent_id=0) | |—层级1: | 2-电子书刊 (parent_id=1) | | | |—层级2: | 3-电子书 (parent_id=2) | 4-网络原创 (parent_id=2) | 5-数字杂志 (parent_id=2) | |—层级1: 7-音像 (parent_id=1) | |—层级2: 8-音乐 (parent_id=7) 9-影视 (parent_id=7) ``` #### 步骤2 - 判断是否为父分类 - 当`is_parent=1`时,该分类下**必须存在**`parent_id`指向它的子分类 $$ \exists child \in T, \text{ s.t. } child.parent\_id = parent.id $$ - 示例:分类2(电子书刊)的`is_parent=1`,因为存在分类3/4/5的`parent_id=2` --- ### 三、实际应用场景 #### 场景1 - 前端展示分类树 ```sql -- 查询所有顶级分类 SELECT * FROM t_product_category WHERE parent_id = 0 AND status=1 ORDER BY sort_order; -- 查询指定分类的子分类(如查询电子书刊的子分类) SELECT * FROM t_product_category WHERE parent_id = 2 AND status=1 ORDER BY sort_order; ``` #### 场景2 - 新增分类 ```sql -- 添加"有声书"到"电子书刊"下,需同步更新父分类状态 INSERT INTO t_product_category (id, parent_id, name, is_parent, sort_order) VALUES (10, 2, '有声书', 0, 5); UPDATE t_product_category SET is_parent=1 WHERE id=2; -- 确保父分类标记正确 ``` --- ### 四、设计优缺点分析 | 优点 | 缺点 | |------------------------------|-------------------------------------| | ✅ 灵活支持无限级分类 | ❌ 查询全树需递归或多次SQL查询 | | ✅ 通过`sort_order`控制展示顺序 | ❌ 维护`is_parent`字段需要额外逻辑 | | ✅ 软删除设计(status=0) | ❌ 深度较大时性能下降 | --- ### 五、最佳实践建议 1. **缓存优化**:将分类树缓存在Redis中,减少数据库访问 2. **路径追踪**:添加`path`字段存储分类链(如`1/2/3`),加速层级查询 3. **异步更新**:使用消息队列异步更新`is_parent`状态,避免阻塞主流程 此设计适用于中小型电商系统,如需处理超大规模数据,建议结合**闭包表(Closure Table)**优化查询效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值